* bug#43559: 28.0.50; [PATCH] Add csharp support to cc-mode @ 2020-09-22 10:37 Theodor Thornhill via Bug reports for GNU Emacs, the Swiss army knife of text editors 2020-09-22 12:51 ` Jostein Kjønigsen 2020-09-23 10:11 ` Alan Mackenzie 0 siblings, 2 replies; 15+ messages in thread From: Theodor Thornhill via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2020-09-22 10:37 UTC (permalink / raw) To: 43559; +Cc: acm, jostein [-- Attachment #1: Type: text/plain, Size: 1671 bytes --] Hello! For some time, I've been a little dissatisfied with the support for C# in emacs. Recently, there has been some breakage in handling of strings and fontification, more precisely: - https://github.com/josteink/csharp-mode/issues/162 Also, it is using a lot of internal c-mode functions: - https://github.com/josteink/csharp-mode/issues/162 I've had some discussions with with the current maintainer, Jostein Kjønigsen (cc'd) about the future of this mode in https://github.com/josteink/csharp-mode/issues/162. Some points of note: - It cannot easily be donated to emacs due to paperwork - Jostein does not have time to do it himself - I took upon myself to rewrite it in a separate branch, as an end goal for it to be included in emacs While working on this, I realized the easiest way to get something good here is to overall reduce the complexity. As such I created this patch. It seems to work nicely, removing the need for the external mode completely. However, I see that including csharp here is most likely a bigger effort than just sending this patch, but I wanted to send what I have, and hopefully get some pointers. Or in worst case stop before I go too far.. This patch is written without consulting the current mode, so paperwork should not be an issue. In addition, the current mode has an implementation of imenu rewritten from scratch by Jostein, and as such I think this can be included as well. I tried not to do too much, since I believe most of the advanced functionality should be provided by an lsp mode such as eglot or lsp-mode. Have a nice day! Theodor Thornhill [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: 0001-Add-csharp-support-to-cc-mode.patch --] [-- Type: text/x-patch, Size: 26736 bytes --] From bb5bd8390ac969bad593b1c9383ce6e2bd0e7cf7 Mon Sep 17 00:00:00 2001 From: Theodor Thornhill <theo@thornhill.no> Date: Tue, 22 Sep 2020 12:09:38 +0200 Subject: [PATCH] Add csharp support to cc-mode --- lisp/progmodes/cc-defs.el | 27 +++---- lisp/progmodes/cc-fonts.el | 33 ++++++++ lisp/progmodes/cc-langs.el | 149 +++++++++++++++++++++++------------- lisp/progmodes/cc-mode.el | 65 +++++++++++++--- lisp/progmodes/cc-styles.el | 37 +++++++++ lisp/progmodes/cc-vars.el | 22 ++++++ 6 files changed, 255 insertions(+), 78 deletions(-) diff --git a/lisp/progmodes/cc-defs.el b/lisp/progmodes/cc-defs.el index 77e263f1aa..ac1c421e37 100644 --- a/lisp/progmodes/cc-defs.el +++ b/lisp/progmodes/cc-defs.el @@ -95,12 +95,12 @@ c-version-sym (defvar c-buffer-is-cc-mode nil "Non-nil for all buffers with a major mode derived from CC Mode. -Otherwise, this variable is nil. I.e. this variable is non-nil for -`c-mode', `c++-mode', `objc-mode', `java-mode', `idl-mode', -`pike-mode', `awk-mode', and any other non-CC Mode mode that calls -`c-initialize-cc-mode'. The value is the mode symbol itself -\(i.e. `c-mode' etc) of the original CC Mode mode, or just t if it's -not known.") +Otherwise, this variable is nil. I.e. this variable is non-nil +for `c-mode', `c++-mode', `objc-mode', `csharp-mode', +`java-mode', `idl-mode', `pike-mode', `awk-mode', and any other +non-CC Mode mode that calls `c-initialize-cc-mode'. The value is +the mode symbol itself \(i.e. `c-mode' etc) of the original CC +Mode mode, or just t if it's not known.") (make-variable-buffer-local 'c-buffer-is-cc-mode) ;; Have to make `c-buffer-is-cc-mode' permanently local so that it @@ -1874,13 +1874,14 @@ c-keep-region-active (and (boundp 'zmacs-region-stays) (setq zmacs-region-stays t))) -(put 'c-mode 'c-mode-prefix "c-") -(put 'c++-mode 'c-mode-prefix "c++-") -(put 'objc-mode 'c-mode-prefix "objc-") -(put 'java-mode 'c-mode-prefix "java-") -(put 'idl-mode 'c-mode-prefix "idl-") -(put 'pike-mode 'c-mode-prefix "pike-") -(put 'awk-mode 'c-mode-prefix "awk-") +(put 'c-mode 'c-mode-prefix "c-") +(put 'c++-mode 'c-mode-prefix "c++-") +(put 'objc-mode 'c-mode-prefix "objc-") +(put 'csharp-mode 'c-mode-prefix "csharp-") +(put 'java-mode 'c-mode-prefix "java-") +(put 'idl-mode 'c-mode-prefix "idl-") +(put 'pike-mode 'c-mode-prefix "pike-") +(put 'awk-mode 'c-mode-prefix "awk-") (defsubst c-mode-symbol (suffix) "Prefix the current mode prefix (e.g. \"c-\") to SUFFIX and return diff --git a/lisp/progmodes/cc-fonts.el b/lisp/progmodes/cc-fonts.el index bb7e5bea6e..c361609e0f 100644 --- a/lisp/progmodes/cc-fonts.el +++ b/lisp/progmodes/cc-fonts.el @@ -2579,6 +2579,39 @@ objc-font-lock-keywords (setq objc-font-lock-extra-types (cc-eval-when-compile (list (concat "[" c-upper "]\\sw*"))))) +\f +;;; Csharp. + +(c-override-default-keywords 'csharp-font-lock-keywords) + +(defconst csharp-font-lock-keywords-1 (c-lang-const c-matchers-1 csharp) + "Minimal font locking for C# mode. +Fontifies nothing except the syntactic fontification of strings and +comments.") + +(defconst csharp-font-lock-keywords-2 (c-lang-const c-matchers-2 csharp) + "Fast normal font locking for C# mode. +In addition to `csharp-font-lock-keywords-1', this adds fontification of +keywords, simple types, declarations that are easy to recognize, the +user defined types on `csharp-font-lock-extra-types', and the doc +comment styles specified by `c-doc-comment-style'.") + +(defconst csharp-font-lock-keywords-3 (c-lang-const c-matchers-3 csharp) + "Accurate normal font locking for C# mode. +Like variable `csharp-font-lock-keywords-2' but detects declarations in a more +accurate way that works in most cases for arbitrary types without the +need for `csharp-font-lock-extra-types'.") + +(defvar csharp-font-lock-keywords csharp-font-lock-keywords-3 + "Default expressions to highlight in C# mode.") + +(defun csharp-font-lock-keywords-2 () + (c-compose-keywords-list csharp-font-lock-keywords-2)) +(defun csharp-font-lock-keywords-3 () + (c-compose-keywords-list csharp-font-lock-keywords-3)) +(defun csharp-font-lock-keywords () + (c-compose-keywords-list csharp-font-lock-keywords)) + \f ;;; Java. diff --git a/lisp/progmodes/cc-langs.el b/lisp/progmodes/cc-langs.el index 13e70a3251..65b1419bb1 100644 --- a/lisp/progmodes/cc-langs.el +++ b/lisp/progmodes/cc-langs.el @@ -378,7 +378,8 @@ c-make-mode-syntax-table (let ((table (make-syntax-table))) (c-populate-syntax-table table) ;; Mode specific syntaxes. - ,(cond ((or (c-major-mode-is 'objc-mode) (c-major-mode-is 'java-mode)) + ,(cond ((or (c-major-mode-is 'objc-mode) (c-major-mode-is 'java-mode) + (c-major-mode-is 'csharp-mode)) ;; Let '@' be part of symbols in ObjC to cope with ;; its compiler directives as single keyword tokens. ;; This is then necessary since it's assumed that @@ -430,7 +431,7 @@ c-identifier-syntax-modifications ;; it as an identifier character since it's often used in various ;; machine generated identifiers. t '((?_ . "w") (?$ . "w")) - (objc java) (append '((?@ . "w")) + (objc java csharp) (append '((?@ . "w")) (c-lang-const c-identifier-syntax-modifications)) awk '((?_ . "w"))) (c-lang-defvar c-identifier-syntax-modifications @@ -467,6 +468,9 @@ c-get-state-before-change-functions c-truncate-bs-cache c-before-change-check-unbalanced-strings c-parse-quotes-before-change) + csharp '(c-parse-quotes-before-change + c-before-change-check-unbalanced-strings + c-before-change-check-<>-operators) java '(c-parse-quotes-before-change c-before-change-check-unbalanced-strings c-before-change-check-<>-operators) @@ -516,6 +520,12 @@ c-before-font-lock-functions c-neutralize-syntax-in-CPP c-restore-<>-properties c-change-expand-fl-region) + csharp '(c-depropertize-new-text + c-after-change-escape-NL-in-string + c-parse-quotes-after-change + c-after-change-mark-abnormal-strings + c-restore-<>-properties + c-change-expand-fl-region) java '(c-depropertize-new-text c-after-change-escape-NL-in-string c-parse-quotes-after-change @@ -648,10 +658,11 @@ c-symbol-start "Regexp that matches the start of a symbol, i.e. any identifier or keyword. It's unspecified how far it matches. Does not contain a \\| operator at the top level." - t (concat "[" c-alpha "_]") - java (concat "[" c-alpha "_@]") - objc (concat "[" c-alpha "_@]") - pike (concat "[" c-alpha "_`]")) + t (concat "[" c-alpha "_]") + csharp (concat "[" c-alpha "_@]") + java (concat "[" c-alpha "_@]") + objc (concat "[" c-alpha "_@]") + pike (concat "[" c-alpha "_`]")) (c-lang-defvar c-symbol-start (c-lang-const c-symbol-start)) (c-lang-defconst c-symbol-chars @@ -718,6 +729,7 @@ c-identifier-ops ;; naming conventions. We still define "." here to make ;; `c-forward-name' move over as long names as possible which is ;; necessary to e.g. handle throws clauses correctly. + csharp '((left-assoc ".")) java '((left-assoc ".")) idl '((left-assoc "::") (prefix "::")) @@ -1247,6 +1259,8 @@ c-overloadable-operators "<<" ">>" ">>=" "<<=" "==" "!=" "not_eq" "<=" ">=" "&&" "and" "||" "??!??!" "or" "++" "--" "," "->*" "->" "()" "[]" "<::>" "??(??)") + csharp '("+" "-" "*" "/" "%" "&" "|" "^" "<<" ">>" "==" + "!=" ">" "<" ">=" "<=") ;; These work like identifiers in Pike. pike '("`+" "`-" "`&" "`|" "`^" "`<<" "`>>" "`*" "`/" "`%" "`~" "`==" "`<" "`>" "`!" "`[]" "`[]=" "`->" "`->=" "`()" "``+" @@ -2023,6 +2037,8 @@ c-primitive-type-kwds objc (append '("id" "Class" "SEL" "IMP" "BOOL") (c-lang-const c-primitive-type-kwds)) + csharp '("bool" "byte" "sbyte" "char" "decimal" "double" "float" "int" "uint" + "long" "ulong" "short" "ushort" "void" "object" "string") java '("boolean" "byte" "char" "double" "float" "int" "long" "short" "void") idl '("Object" "ValueBase" "any" "boolean" "char" "double" "fixed" "float" "long" "octet" "sequence" "short" "string" "void" "wchar" "wstring" @@ -2137,7 +2153,8 @@ c-type-modifier-kwds on `c-primitive-type-kwds', they are fontified with the keyword face and not the type face." t (c-lang-const c-type-modifier-prefix-kwds) - c++ (append (c-lang-const c-type-modifier-prefix-kwds) '("throw"))) + c++ (append (c-lang-const c-type-modifier-prefix-kwds) '("throw")) + csharp '("readonly" "const" "volatile" "new")) (c-lang-defconst c-opt-type-modifier-key ;; Adorned regexp matching `c-type-modifier-kwds', or nil in @@ -2229,8 +2246,9 @@ c-brace-list-decl-kwds `c-colon-type-list-kwds', `c-paren-nontype-kwds', `c-paren-type-kwds', `c-<>-type-kwds', or `c-<>-arglist-kwds' then the associated clauses will be handled." - t '("enum") - (awk) nil) + t '("enum") + csharp '("enum" "new") + (awk) nil) (c-lang-defconst c-brace-list-key ;; Regexp matching the start of declarations where the following @@ -2281,6 +2299,7 @@ c-other-block-decl-kwds t nil (c objc) '("extern") c++ '("namespace" "extern") + csharp '("namespace") idl '("module" ;; In CORBA CIDL: "composition")) @@ -2341,7 +2360,8 @@ c-typedef-decl-key (c-lang-defconst c-using-kwds "Keywords which behave like `using' in C++" t nil - c++ '("using")) + c++ '("using") + csharp '("using")) (c-lang-defconst c-using-key ;; Regexp matching C++'s `using'. @@ -2410,6 +2430,10 @@ c-modifier-kwds "primary" "state" ;; In CORBA CIDL: "bindsTo" "delegatesTo" "implements" "proxy" "storedOn") + csharp '("abstract" "const" "default" "final" "native" "private" "protected" + "public" "partial" "internal" "readonly" "static" "event" "transient" + "volatile" "sealed" "ref" "out" "virtual" "implicit" "explicit" + "fixed" "override" "params" "async" "extern" "unsafe") ;; Note: "const" is not used in Java, but it's still a reserved keyword. java '("abstract" "const" "default" "final" "native" "private" "protected" "public" "static" "strictfp" "synchronized" "transient" "volatile") @@ -2634,14 +2658,16 @@ c-type-list-kwds Note: Use `c-typeless-decl-kwds' for keywords followed by a function or variable identifier (that's being defined)." - t nil - c++ '("operator") - objc '("@class") - java '("import" "new" "extends" "super" "implements" "throws") - idl '("manages" "native" "primarykey" "supports" - ;; In CORBA PSDL: - "as" "implements" "of" "scope") - pike '("inherit")) + t nil + c++ '("operator") + objc '("@class") + csharp '("struct" "class" "interface" "delegate" "event" "get" "set" "add" + "remove" "is" "as" "operator") + java '("import" "new" "extends" "super" "implements" "throws") + idl '("manages" "native" "primarykey" "supports" + ;; In CORBA PSDL: + "as" "implements" "of" "scope") + pike '("inherit")) (c-lang-defconst c-ref-list-kwds "Keywords that may be followed by a comma separated list of @@ -2652,24 +2678,26 @@ c-ref-list-kwds Note: Use `c-typeless-decl-kwds' for keywords followed by a function or variable identifier (that's being defined)." - t nil - c++ '("namespace") - java '("package") - idl '("import" "module" - ;; In CORBA CIDL: - "composition") - pike '("import")) + t nil + c++ '("namespace") + csharp '("var") + java '("package") + idl '("import" "module" + ;; In CORBA CIDL: + "composition") + pike '("import")) (c-lang-defconst c-colon-type-list-kwds "Keywords that may be followed (not necessarily directly) by a colon and then a comma separated list of type identifiers, where each optionally can be prefixed by keywords. (Can also be used for the special case when the list can contain only one element.)" - t nil - c++ '("class" "struct") - idl '("component" "eventtype" "home" "interface" "valuetype" - ;; In CORBA PSDL: - "storagehome" "storagetype")) + t nil + c++ '("class" "struct") + csharp '("class" "struct" "interface") + idl '("component" "eventtype" "home" "interface" "valuetype" + ;; In CORBA PSDL: + "storagehome" "storagetype")) (c-lang-defconst c-colon-type-list-re "Regexp matched after the keywords in `c-colon-type-list-kwds' to skip @@ -2765,11 +2793,12 @@ c-brace-id-list-kwds (c-lang-defconst c-block-stmt-1-kwds "Statement keywords followed directly by a substatement." - t '("do" "else") - c++ '("do" "else" "try") - objc '("do" "else" "@finally" "@try" "@autoreleasepool") - java '("do" "else" "finally" "try") - idl nil) + t '("do" "else") + c++ '("do" "else" "try") + objc '("do" "else" "@finally" "@try" "@autoreleasepool") + csharp '("do" "else" "finally" "try") + java '("do" "else" "finally" "try") + idl nil) (c-lang-defconst c-block-stmt-1-key ;; Regexp matching the start of any statement followed directly by a @@ -2781,7 +2810,8 @@ c-block-stmt-1-2-kwds "Statement keywords optionally followed by a paren sexp. Keywords here should also be in `c-block-stmt-1-kwds'." t nil - java '("try")) + csharp '("try") + java '("try")) (c-lang-defconst c-block-stmt-1-2-key ;; Regexp matching the start of a statement which may be followed by a @@ -2791,13 +2821,15 @@ c-block-stmt-1-2-key (c-lang-defconst c-block-stmt-2-kwds "Statement keywords followed by a paren sexp and then by a substatement." - t '("for" "if" "switch" "while") - c++ '("for" "if" "switch" "while" "catch") - objc '("for" "if" "switch" "while" "@catch" "@synchronized") - java '("for" "if" "switch" "while" "catch" "synchronized") - idl nil - pike '("for" "if" "switch" "while" "foreach") - awk '("for" "if" "switch" "while")) + t '("for" "if" "switch" "while") + c++ '("for" "if" "switch" "while" "catch") + objc '("for" "if" "switch" "while" "@catch" "@synchronized") + csharp '("for" "if" "switch" "while" "catch" "foreach" "fixed" "checked" + "unchecked" "using" "lock") + java '("for" "if" "switch" "while" "catch" "synchronized") + idl nil + pike '("for" "if" "switch" "while" "foreach") + awk '("for" "if" "switch" "while")) (c-lang-defconst c-block-stmt-2-key ;; Regexp matching the start of any statement followed by a paren sexp @@ -2838,6 +2870,7 @@ c-simple-stmt-kwds t '("break" "continue" "goto" "return") c++ '("break" "continue" "goto" "return" "co_return") objc '("break" "continue" "goto" "return" "@throw") + csharp '("break" "continue" "goto" "return" "throw") ;; Note: `goto' is not valid in Java, but the keyword is still reserved. java '("break" "continue" "goto" "return" "throw") idl nil @@ -2912,16 +2945,18 @@ c-constant-kwds objc '("nil" "Nil" "YES" "NO" "IBAction" "IBOutlet" "NS_DURING" "NS_HANDLER" "NS_ENDHANDLER") idl '("TRUE" "FALSE") + csharp '("true" "false" "null" "value") java '("true" "false" "null") ; technically "literals", not keywords pike '("UNDEFINED")) ;; Not a keyword, but practically works as one. (c-lang-defconst c-primary-expr-kwds "Keywords besides constants and operators that start primary expressions." - t nil - c++ '("operator" "this") - objc '("super" "self") - java '("this") - pike '("this")) ;; Not really a keyword, but practically works as one. + t nil + c++ '("operator" "this") + objc '("super" "self") + csharp '("this" "base" "operator") + java '("this") + pike '("this")) ;; Not really a keyword, but practically works as one. (c-lang-defconst c-expr-kwds ;; Keywords that can occur anywhere in expressions. Built from @@ -2948,16 +2983,18 @@ c-inexpr-block-kwds (c-lang-defconst c-inexpr-class-kwds "Keywords that can start classes inside expressions." - t nil - java '("new") - pike '("class")) + t nil + csharp '("new") + java '("new") + pike '("class")) (c-lang-defconst c-inexpr-brace-list-kwds "Keywords that can start brace list blocks inside expressions. Note that Java specific rules are currently applied to tell this from `c-inexpr-class-kwds'." - t nil - java '("new")) + t nil + csharp '("new") + java '("new")) (c-lang-defconst c-opt-inexpr-brace-list-key ;; Regexp matching the start of a brace list in an expression, or @@ -3049,6 +3086,7 @@ c-std-abbrev-keywords "List of keywords which may need to cause electric indentation." t '("else" "while") c++ (append (c-lang-const c-std-abbrev-keywords) '("catch")) + csharp (append (c-lang-const c-std-abbrev-keywords) '("catch" "finally")) java (append (c-lang-const c-std-abbrev-keywords) '("catch" "finally")) idl nil) (c-lang-defvar c-std-abbrev-keywords (c-lang-const c-std-abbrev-keywords)) @@ -3274,6 +3312,7 @@ c-decl-prefix-re ;; in all languages except Java for when a cpp macro definition ;; begins with a declaration. t "\\([{}();,]+\\)" + csharp "\\([{}(;,<]+\\)" java "\\([{}(;,<]+\\)" ;; Match "<" in C++ to get the first argument in a template arglist. ;; In that case there's an additional check in `c-find-decl-spots' @@ -3585,6 +3624,7 @@ c-opt-type-suffix-key is in effect or not." t nil (c c++ objc pike) "\\(\\.\\.\\.\\)" + csharp (concat "\\(\\[" (c-lang-const c-simple-ws) "*\\]\\|\\.\\.\\.\\)") java (concat "\\(\\[" (c-lang-const c-simple-ws) "*\\]\\|\\.\\.\\.\\)")) (c-lang-defvar c-opt-type-suffix-key (c-lang-const c-opt-type-suffix-key)) @@ -3644,7 +3684,7 @@ c-recognize-typeless-decls that are preceded by a declaration starting keyword, so e.g. `c-typeless-decl-kwds' may still be used when it's set to nil." t nil - (c c++ objc java) t) + (c c++ objc csharp java) t) (c-lang-defvar c-recognize-typeless-decls (c-lang-const c-recognize-typeless-decls)) @@ -3657,6 +3697,7 @@ c-recognize-<>-arglists expression is considered to be a type." t (or (consp (c-lang-const c-<>-type-kwds)) (consp (c-lang-const c-<>-arglist-kwds))) + csharp t java t) ; 2008-10-19. This is crude. The syntax for java ; generics is not yet coded in CC Mode. (c-lang-defvar c-recognize-<>-arglists (c-lang-const c-recognize-<>-arglists)) diff --git a/lisp/progmodes/cc-mode.el b/lisp/progmodes/cc-mode.el index c6dd671051..56cc476fad 100644 --- a/lisp/progmodes/cc-mode.el +++ b/lisp/progmodes/cc-mode.el @@ -36,12 +36,12 @@ ;; Note: The version string is in cc-defs. ;; This package provides GNU Emacs major modes for editing C, C++, -;; Objective-C, Java, CORBA's IDL, Pike and AWK code. As of the +;; Objective-C, C#, Java, CORBA's IDL, Pike and AWK code. As of the ;; latest Emacs and XEmacs releases, it is the default package for ;; editing these languages. This package is called "CC Mode", and ;; should be spelled exactly this way. -;; CC Mode supports K&R and ANSI C, ANSI C++, Objective-C, Java, +;; CC Mode supports K&R and ANSI C, ANSI C++, Objective-C, C#, Java, ;; CORBA's IDL, Pike and AWK with a consistent indentation model ;; across all modes. This indentation model is intuitive and very ;; flexible, so that almost any desired style of indentation can be @@ -75,7 +75,6 @@ ;; Externally maintained major modes which use CC-mode's engine include: ;; - cuda-mode -;; - csharp-mode (https://github.com/josteink/csharp-mode) ;; - haxe-mode ;; - d-mode ;; - dart-mode @@ -195,13 +194,14 @@ c-init-language-vars-for `c-init-language-vars' macro if the language you want to use is one of those, rather than a derived language defined through the language variable system (see \"cc-langs.el\")." - (cond ((eq mode 'c-mode) (c-init-language-vars c-mode)) - ((eq mode 'c++-mode) (c-init-language-vars c++-mode)) - ((eq mode 'objc-mode) (c-init-language-vars objc-mode)) - ((eq mode 'java-mode) (c-init-language-vars java-mode)) - ((eq mode 'idl-mode) (c-init-language-vars idl-mode)) - ((eq mode 'pike-mode) (c-init-language-vars pike-mode)) - ((eq mode 'awk-mode) (c-init-language-vars awk-mode)) + (cond ((eq mode 'c-mode) (c-init-language-vars c-mode)) + ((eq mode 'c++-mode) (c-init-language-vars c++-mode)) + ((eq mode 'objc-mode) (c-init-language-vars objc-mode)) + ((eq mode 'csharp-mode) (c-init-language-vars csharp-mode)) + ((eq mode 'java-mode) (c-init-language-vars java-mode)) + ((eq mode 'idl-mode) (c-init-language-vars idl-mode)) + ((eq mode 'pike-mode) (c-init-language-vars pike-mode)) + ((eq mode 'awk-mode) (c-init-language-vars awk-mode)) (t (error "Unsupported mode %s" mode)))) ;;;###autoload @@ -649,7 +649,8 @@ c-basic-common-init (when (or c-recognize-<>-arglists (c-major-mode-is 'awk-mode) - (c-major-mode-is '(java-mode c-mode c++-mode objc-mode pike-mode))) + (c-major-mode-is + '(java-mode c-mode c++-mode objc-mode pike-mode csharp-mode))) ;; We'll use the syntax-table text property to change the syntax ;; of some chars for this language, so do the necessary setup for ;; that. @@ -2739,6 +2740,48 @@ objc-mode (cc-imenu-init nil 'cc-imenu-objc-function) (c-run-mode-hooks 'c-mode-common-hook)) +\f +;; Support for C# + +(defvar csharp-mode-syntax-table + (funcall (c-lang-const c-make-mode-syntax-table csharp)) + "Syntax table used in csharp-mode buffers.") + +(defvar csharp-mode-map + (let ((map (c-make-inherited-keymap))) + map) + "Keymap used in csharp-mode buffers.") +;; Add bindings which are only useful for C#. + +(easy-menu-define c-csharp-menu csharp-mode-map "C# Mode Commands" + (cons "C#" (c-lang-const c-mode-menu csharp))) + +;;;###autoload (add-to-list 'auto-mode-alist '("\\.cs\\'" . csharp-mode)) + +;;;###autoload +(define-derived-mode csharp-mode prog-mode "C#" + "Major mode for editing Csharp code. +To submit a problem report, enter `\\[c-submit-bug-report]' from a +csharp-mode buffer. This automatically sets up a mail buffer with +version information already added. You just need to add a description +of the problem, including a reproducible test case, and send the +message. + +To see what version of CC Mode you are running, enter `\\[c-version]'. + +The hook `c-mode-common-hook' is run with no args at mode +initialization, then `csharp-mode-hook'. + +Key bindings: +\\{csharp-mode-map}" + :after-hook (c-update-modeline) + (c-initialize-cc-mode t) + (setq abbrev-mode t) + (c-init-language-vars-for 'csharp-mode) + (c-common-init 'csharp-mode) + (easy-menu-add c-csharp-menu) + (c-run-mode-hooks 'c-mode-common-hook)) + \f ;; Support for Java diff --git a/lisp/progmodes/cc-styles.el b/lisp/progmodes/cc-styles.el index 36be9f6c74..4b84bd7dff 100644 --- a/lisp/progmodes/cc-styles.el +++ b/lisp/progmodes/cc-styles.el @@ -215,6 +215,43 @@ c-style-alist (arglist-cont-nonempty))) (c-block-comment-prefix . "")) + ("csharp" + (c-basic-offset . 4) + (c-comment-only-line-offset . (0 . 0)) + (c-offsets-alist . ((inline-open . 0) + (topmost-intro . 0) + (topmost-intro-cont . +) + (statement-block-intro . +) + (statement-case-intro . +) + (statement-case-open . +) + (substatement . +) + (substatement-open . 0) + (substatement-label . +) + (label . +) + (statement-case-open . +) + (statement-cont . +) + (arglist-intro . c-lineup-arglist-intro-after-paren) + (arglist-close . c-lineup-arglist) + (string . c-lineup-dont-change) + (arglist-cont . 0) + (block-open . 0) + (block-close . 0) + (block-list-entry . 0) + (block-list-open . 0) + (block-list-close . 0) + (case-label . +) + (catch-label . 0) + (class-open . 0) + (class-close . 0) + (defun-open . 0) + (defun-close . 0) + (else-clause . 0) + (brace-list-intro . (first + c-lineup-2nd-brace-entry-in-arglist + c-lineup-class-decl-init-+ +)) + (access-label . -) + (inher-cont . c-lineup-java-inher) + (func-decl-cont . c-lineup-java-throws)))) ("java" (c-basic-offset . 4) (c-comment-only-line-offset . (0 . 0)) diff --git a/lisp/progmodes/cc-vars.el b/lisp/progmodes/cc-vars.el index 9e6f9527ca..559531fafe 100644 --- a/lisp/progmodes/cc-vars.el +++ b/lisp/progmodes/cc-vars.el @@ -549,6 +549,8 @@ c-comment-prefix-regexp (const :format "C++ " c++-mode) (regexp :format "%v")) (cons :format "%v" (const :format "ObjC " objc-mode) (regexp :format "%v")) + (cons :format "%v" + (const :format "C# " csharp-mode) (regexp :format "%v")) (cons :format "%v" (const :format "Java " java-mode) (regexp :format "%v")) (cons :format "%v" @@ -919,6 +921,9 @@ c-require-final-newline (cons :format "%v" (const :format "ObjC " objc-mode) (symbol :format "%v" :value ,require-final-newline)) + (cons :format "%v" + (const :format "C# " csharp-mode) + (symbol :format "%v" :value ,require-final-newline)) (cons :format "%v" (const :format "Java " java-mode) (symbol :format "%v" :value ,require-final-newline)) @@ -1003,6 +1008,7 @@ c-objc-method-parameter-offset :group 'c) (defcustom c-default-style '((java-mode . "java") (awk-mode . "awk") + (csharp-mode . "csharp") (other . "gnu")) "Style which gets installed by default when a file is visited. @@ -1031,6 +1037,8 @@ c-default-style (const :format "C++ " c++-mode) (string :format "%v")) (cons :format "%v" (const :format "ObjC " objc-mode) (string :format "%v")) + (cons :format "%v" + (const :format "C# " csharp-mode) (string :format "%v")) (cons :format "%v" (const :format "Java " java-mode) (string :format "%v")) (cons :format "%v" @@ -1459,6 +1467,11 @@ objc-mode-hook :type 'hook :group 'c) +(defcustom csharp-mode-hook nil + "Hook called by `csharp-mode'." + :type 'hook + :group 'c) + (defcustom java-mode-hook nil "Hook called by `java-mode'." :type 'hook @@ -1613,6 +1626,15 @@ objc-font-lock-extra-types :type 'c-extra-types-widget :group 'c) +(defcustom csharp-font-lock-extra-types + (list (concat "[" c-upper "]\\sw*[" c-lower "]\\sw")) + (c-make-font-lock-extra-types-blurb "C#" "csharp-mode" (concat +"For example, a value of (\"[" c-upper "]\\\\sw*[" c-lower "]\\\\sw*\") means +capitalized words are treated as type names (the requirement for a +lower case char is to avoid recognizing all-caps constant names).")) + :type 'c-extra-types-widget + :group 'c) + (defcustom java-font-lock-extra-types (list (concat "[" c-upper "]\\sw*[" c-lower "]\\sw")) (c-make-font-lock-extra-types-blurb "Java" "java-mode" (concat -- 2.28.0 ^ permalink raw reply related [flat|nested] 15+ messages in thread
* bug#43559: 28.0.50; [PATCH] Add csharp support to cc-mode 2020-09-22 10:37 bug#43559: 28.0.50; [PATCH] Add csharp support to cc-mode Theodor Thornhill via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2020-09-22 12:51 ` Jostein Kjønigsen 2020-09-22 13:10 ` Theodor Thornhill via Bug reports for GNU Emacs, the Swiss army knife of text editors 2020-09-23 10:11 ` Alan Mackenzie 1 sibling, 1 reply; 15+ messages in thread From: Jostein Kjønigsen @ 2020-09-22 12:51 UTC (permalink / raw) To: theo, 43559; +Cc: acm, jostein [-- Attachment #1: Type: text/plain, Size: 947 bytes --] Hey Theo. Thanks for your work on trying to get something new, and possibly better C#-support mainlined in Emacs! Not commenting on the patch itself, but in your email you had some links to Github issues which were not correct. To assist the further conversation, I'll just provide pointers to the actual issues below. On 22.09.2020 12:37, Theodor Thornhill wrote: > Also, it is using a lot of internal c-mode functions: > - https://github.com/josteink/csharp-mode/issues/162 This link should be: https://github.com/josteink/csharp-mode/issues/128 > > I've had some discussions with with the current maintainer, Jostein > Kjønigsen (cc'd) about the future of this mode in > https://github.com/josteink/csharp-mode/issues/162. This link should be: https://github.com/josteink/csharp-mode/issues/153 Hope this helps. -- Kind regards *Jostein Kjønigsen* jostein@kjonigsen.net 🍵 jostein@gmail.com https://jostein.kjønigsen.no [-- Attachment #2: Type: text/html, Size: 2150 bytes --] ^ permalink raw reply [flat|nested] 15+ messages in thread
* bug#43559: 28.0.50; [PATCH] Add csharp support to cc-mode 2020-09-22 12:51 ` Jostein Kjønigsen @ 2020-09-22 13:10 ` Theodor Thornhill via Bug reports for GNU Emacs, the Swiss army knife of text editors 2020-09-22 14:26 ` Jostein Kjønigsen 0 siblings, 1 reply; 15+ messages in thread From: Theodor Thornhill via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2020-09-22 13:10 UTC (permalink / raw) To: jostein, 43559; +Cc: acm Jostein Kjønigsen <jostein@secure.kjonigsen.net> writes: > Hey Theo. > > Thanks for your work on trying to get something new, and possibly better > C#-support mainlined in Emacs! My pleasure - hopefully we'll get there :) [...] > On 22.09.2020 12:37, Theodor Thornhill wrote: >> Also, it is using a lot of internal c-mode functions: >> - https://github.com/josteink/csharp-mode/issues/162 > > This link should be: https://github.com/josteink/csharp-mode/issues/128 > >> >> I've had some discussions with with the current maintainer, Jostein >> Kjønigsen (cc'd) about the future of this mode in >> https://github.com/josteink/csharp-mode/issues/162. > > This link should be: https://github.com/josteink/csharp-mode/issues/153 > When you think you can copy paste... Thanks for correcting here. Don't know how I managed that :) Theo ^ permalink raw reply [flat|nested] 15+ messages in thread
* bug#43559: 28.0.50; [PATCH] Add csharp support to cc-mode 2020-09-22 13:10 ` Theodor Thornhill via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2020-09-22 14:26 ` Jostein Kjønigsen 2020-09-22 21:15 ` Theodor Thornhill via Bug reports for GNU Emacs, the Swiss army knife of text editors 0 siblings, 1 reply; 15+ messages in thread From: Jostein Kjønigsen @ 2020-09-22 14:26 UTC (permalink / raw) To: theo, 43559; +Cc: acm [-- Attachment #1: Type: text/plain, Size: 4819 bytes --] On 22.09.2020 15:10, Theodor Thornhill wrote: > Jostein Kjønigsen <jostein@secure.kjonigsen.net> writes: > >> Hey Theo. >> >> Thanks for your work on trying to get something new, and possibly better >> C#-support mainlined in Emacs! > My pleasure - hopefully we'll get there :) > > [...] > Hey Theo. I still haven't looked at the code in your patch, but I've applied it to latest Emacs Git master, and given it a test-run. When going over existing code, everything looks and feels nice. And it's much faster than my "old", non-transferable code. So I definitely think this is a /very good/ start. While I hold no "position" in GNU or Emacs as a whole, I would consider myself a C# veteran (since 2004), and as the old maintainer of old csharp-mode, I think I have some experience which may be useful. So for the time being, I'll just promote myself to being the "critical Emacs C#-user", and provide some feedback based on my expectations for how editing C# should feel or behave. Please don't consider the following comments as negative towards your work, or me in any way trying to dissuade you from getting this mainlined. I'm just here to try to help you ensure that what you land is going to be "good enough" so that it will be easier to argue for inclusion in core-Emacs later on :) So with all that said, so far I've noticed a few things which I think arguably goes against C# convention, and would be nice to get fixed, if possible. There's also a some things where I just feel it would "better" to do things differently. Roughly it boils down to this list: 1. Attributes 2. Object initializers 3. Lambda indentation 4. Misc variables/field fontification issues *First off: **Attributes are not handled properly. ** * In java-mode annotations gets fontified and indented properly: In your current csharp-mode draft, we get no fontification, and we also get a trailing indentation bug for the equivalent C# code: For annotation-heavy frameworks like ASP.Net Core this might get annoying. It would be great if this could get fixed. *Second: Object initializers are not indented properly.* Consider the following fairly simple case. Using the provided patch we get the following indentation: According to C# convention, one would expect something more like this: This one is arguably very hard to get right, because it's a conceptually infinitely recursive problem. (You may initialize a property with another object-initializer.) While solving this perfectly for all cases is clearly out the window, do you think it would be possible at least to make 1-level object-initilizers work? One the bright side /collection-/initializers seems to work just fine :) *Third: Lamda-function indentation when used with higher order functions * Lambdas also suffer from some unexpected indentation issues: Here I would expect the following indentation instead: *Fourth: variable-fontification* Here I have no absolute C# convention to quote for absolute correctness, but it kinda "feels wrong" to me at places. Without a proper language-engine to guide us, it will be literally impossible to know what is a class, a namespace, an enum, a local field or an actual variable at any point in the code, and fontify the code 100% correctly based on that. So we'll have to make due with imperfections, make some pragmatical decisions on what we think will be good default/fallback values, and that's OK. Right now though, all implicitly typed variables (vars), local variables with method-access and local fields with property-access are shown using /font-lock-constant-face/ and that seems a bit off: For var-heavy functions, this inconsistency is somewhat distracting, and I would much prefer a font-lock-variable-face fallback in these cases. As for "_field" and "foo.", I'm not sure what the best fallback would be. Without a language-engine to guide us, this is genuinely hard stuff to get right. By C# convention pascalCased or _underCased identifiers typically represent local variables and object-local fields (and thus might use font-lock-variable-face as a fallback). Conversely CamelCased identifiers typically represent either Classes or public properties/methods on those, depending on identifier in question being dot-accessed or not (and for these another face might make more sense). I'm sure just/discussing/ the///soft-rules/ for these aspects could take months alone, not speaking for the effort required to actually making it happen in code. Consider it something to aim for, but I wouldn't expect anyone to get this right in a version 1 of anything. Otherwise, great work, and thank you for putting in this effort! -- Kind regards *Jostein Kjønigsen* jostein@kjonigsen.net 🍵 jostein@gmail.com https://jostein.kjønigsen.no [-- Attachment #2.1: Type: text/html, Size: 7246 bytes --] [-- Attachment #2.2: nhebmpbbonkfichd.png --] [-- Type: image/png, Size: 7374 bytes --] [-- Attachment #2.3: epihfhegglofbbha.png --] [-- Type: image/png, Size: 7013 bytes --] [-- Attachment #2.4: hfhhbebmljemcgca.png --] [-- Type: image/png, Size: 5608 bytes --] [-- Attachment #2.5: fiaafecacbkbgbkh.png --] [-- Type: image/png, Size: 5475 bytes --] [-- Attachment #2.6: aceilhdglgpjgcad.png --] [-- Type: image/png, Size: 5913 bytes --] [-- Attachment #2.7: mehgknkpcccjilmm.png --] [-- Type: image/png, Size: 6620 bytes --] [-- Attachment #2.8: jognflfdjkamkonl.png --] [-- Type: image/png, Size: 6622 bytes --] [-- Attachment #2.9: igcegelpjofikpgg.png --] [-- Type: image/png, Size: 19080 bytes --] ^ permalink raw reply [flat|nested] 15+ messages in thread
* bug#43559: 28.0.50; [PATCH] Add csharp support to cc-mode 2020-09-22 14:26 ` Jostein Kjønigsen @ 2020-09-22 21:15 ` Theodor Thornhill via Bug reports for GNU Emacs, the Swiss army knife of text editors 2020-09-23 8:46 ` Jostein Kjønigsen 0 siblings, 1 reply; 15+ messages in thread From: Theodor Thornhill via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2020-09-22 21:15 UTC (permalink / raw) To: jostein, 43559; +Cc: acm [-- Attachment #1: Type: text/plain, Size: 6486 bytes --] Jostein Kjønigsen <jostein@secure.kjonigsen.net> writes: > On 22.09.2020 15:10, Theodor Thornhill wrote: >> Jostein Kjønigsen <jostein@secure.kjonigsen.net> writes: [...] > I still haven't looked at the code in your patch, but I've applied it to > latest Emacs Git master, and given it a test-run. > When going over existing code, everything looks and feels nice. And it's > much faster than my "old", non-transferable code. So I definitely think > this is a /very good/ start. Nice! > > While I hold no "position" in GNU or Emacs as a whole, I would consider > myself a C# veteran (since 2004), and as the old maintainer of old > csharp-mode, I think I have some experience which may be useful. Most definitively. Thank you for taking your time! > > So for the time being, I'll just promote myself to being the "critical > Emacs C#-user", and provide some feedback based on my expectations for > how editing C# should feel or behave. > > Please don't consider the following comments as negative towards your > work, or me in any way trying to dissuade you from getting this > mainlined. I'm just here to try to help you ensure that what you land is > going to be "good enough" so that it will be easier to argue for > inclusion in core-Emacs later on :) None of your comment are taken as negative. I'd much rather you'd be critical early, so that we can get something nice quicker! > > So with all that said, so far I've noticed a few things which I think > arguably goes against C# convention, and would be nice to get fixed, if > possible. There's also a some things where I just feel it would "better" > to do things differently. > Before I answer your comments, I'll just let you know I'm still wrapping my head around the whole cc-mode. I might find better solutions to all this later on. > > *First off: **Attributes are not handled properly. ** > * > > In java-mode annotations gets fontified and indented properly: > > In your current csharp-mode draft, we get no fontification, and we also > get a trailing indentation bug for the equivalent C# code: Yeah, this is a difficult one, because the java version of this implements lots of logic in the cc-engine.el, and for now, we don't. However, my most recent patch seems to deal with this properly, as far as I can tell. I've tested with your example code and also with random files in the roslyn repository. Fontification is still sparse here. > > *Second: Object initializers are not indented properly.* > > Consider the following fairly simple case. Using the provided patch we > get the following indentation: This one should be fixed in the attached patch. > This one is arguably very hard to get right, because it's a conceptually > infinitely recursive problem. (You may initialize a property with > another object-initializer.) I think the recursion case works as well. I've made an attempt in the attached 'test.cs' > > While solving this perfectly for all cases is clearly out the window, do > you think it would be possible at least to make 1-level > object-initilizers work? Hopefully, we have it now! > > One the bright side /collection-/initializers seems to work just fine :) > Great! > > *Third: Lamda-function indentation when used with higher order functions > * > > Lambdas also suffer from some unexpected indentation issues: This one should be fixed in the latest patch. > > *Fourth: variable-fontification* > > Here I have no absolute C# convention to quote for absolute correctness, > but it kinda "feels wrong" to me at places. > So we'll have to make due with imperfections, make some pragmatical > decisions on what we think will be good default/fallback values, and > that's OK. > Agreed > Right now though, all implicitly typed variables (vars), local variables > with method-access and local fields with property-access are shown using > /font-lock-constant-face/ and that seems a bit off: This case is fixed now. It was due to the 'var' keyword was put in the wrong basket. > As for "_field" and "foo.", I'm not sure what the best fallback would > be. Without a language-engine to guide us, this is genuinely hard stuff > to get right. > Yeah, this one is kind of hard, so I've been ignoring it for a little while. The easiest thing should be to remove the highlighting, but not sure if that is the best move so far. > > I'm sure just/discussing/ the///soft-rules/ for these aspects could take > months alone, not speaking for the effort required to actually making it > happen in code. > > Consider it something to aim for, but I wouldn't expect anyone to get > this right in a version 1 of anything. > Yeah, more cases are coming up all the time. My initial focus has been mostly on the indentation part, since font-locking is a 'bonus-feature' in some sense. However, they seem intimately connected in cc-mode. > > Otherwise, great work, and thank you for putting in this effort! My pleasure :) One issue I have now is that there are many rules in the c-style-alist, and I think it would be better to design or reuse some constructs from cc-engine to apply some other syntax rules to the code. One example and consequence of this is the fix of the attributes from your code. It aligns nicely, but destroys the indentation of the 'aligned ternary' (on the bottom of the file). Please, if you have time, take a look at the second patch, as well as the test file. Maybe you get some ideas, but I think some of the low hanging fruits are found, and it is time to dive into the engine itself. I really appreciate you taking your time to find these bugs for me. Thanks. -- Theo P.S Pasting the contents of test.cs here, since I apparently suck at email /// Working [Test] public class Foo { [Zoo] [Goo] public void Bar() { } }; var x = new SomeType[] { Prop1 = "foo", Prop2 = new SomeType2[] { Prop3 = true ? "this" : "that"; } // }; var x = new SomeType[] { new SomeType(a, b), new SomeType(b, c) // lol }; /// Kind of working goo.Select(i => { return goo.Select(i) .Foo() .Bar() }); Foo foo = new Foo(); var bar1 = foo.Bar(_field); Bar bar3 = foo.Bar(_field.Prop); /// Not working var x = foo ? bar : baz; [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: v2-0001-Add-csharp-support-to-cc-mode.patch --] [-- Type: text/x-patch, Size: 26693 bytes --] From e3707e7d45d708c20733c7c496b98c1c2724b808 Mon Sep 17 00:00:00 2001 From: Theodor Thornhill <theo@thornhill.no> Date: Tue, 22 Sep 2020 12:09:38 +0200 Subject: [PATCH v2] Add csharp support to cc-mode --- lisp/progmodes/cc-defs.el | 27 +++---- lisp/progmodes/cc-fonts.el | 33 ++++++++ lisp/progmodes/cc-langs.el | 148 +++++++++++++++++++++++------------- lisp/progmodes/cc-mode.el | 65 +++++++++++++--- lisp/progmodes/cc-styles.el | 36 +++++++++ lisp/progmodes/cc-vars.el | 22 ++++++ 6 files changed, 253 insertions(+), 78 deletions(-) diff --git a/lisp/progmodes/cc-defs.el b/lisp/progmodes/cc-defs.el index 77e263f1aa..ac1c421e37 100644 --- a/lisp/progmodes/cc-defs.el +++ b/lisp/progmodes/cc-defs.el @@ -95,12 +95,12 @@ c-version-sym (defvar c-buffer-is-cc-mode nil "Non-nil for all buffers with a major mode derived from CC Mode. -Otherwise, this variable is nil. I.e. this variable is non-nil for -`c-mode', `c++-mode', `objc-mode', `java-mode', `idl-mode', -`pike-mode', `awk-mode', and any other non-CC Mode mode that calls -`c-initialize-cc-mode'. The value is the mode symbol itself -\(i.e. `c-mode' etc) of the original CC Mode mode, or just t if it's -not known.") +Otherwise, this variable is nil. I.e. this variable is non-nil +for `c-mode', `c++-mode', `objc-mode', `csharp-mode', +`java-mode', `idl-mode', `pike-mode', `awk-mode', and any other +non-CC Mode mode that calls `c-initialize-cc-mode'. The value is +the mode symbol itself \(i.e. `c-mode' etc) of the original CC +Mode mode, or just t if it's not known.") (make-variable-buffer-local 'c-buffer-is-cc-mode) ;; Have to make `c-buffer-is-cc-mode' permanently local so that it @@ -1874,13 +1874,14 @@ c-keep-region-active (and (boundp 'zmacs-region-stays) (setq zmacs-region-stays t))) -(put 'c-mode 'c-mode-prefix "c-") -(put 'c++-mode 'c-mode-prefix "c++-") -(put 'objc-mode 'c-mode-prefix "objc-") -(put 'java-mode 'c-mode-prefix "java-") -(put 'idl-mode 'c-mode-prefix "idl-") -(put 'pike-mode 'c-mode-prefix "pike-") -(put 'awk-mode 'c-mode-prefix "awk-") +(put 'c-mode 'c-mode-prefix "c-") +(put 'c++-mode 'c-mode-prefix "c++-") +(put 'objc-mode 'c-mode-prefix "objc-") +(put 'csharp-mode 'c-mode-prefix "csharp-") +(put 'java-mode 'c-mode-prefix "java-") +(put 'idl-mode 'c-mode-prefix "idl-") +(put 'pike-mode 'c-mode-prefix "pike-") +(put 'awk-mode 'c-mode-prefix "awk-") (defsubst c-mode-symbol (suffix) "Prefix the current mode prefix (e.g. \"c-\") to SUFFIX and return diff --git a/lisp/progmodes/cc-fonts.el b/lisp/progmodes/cc-fonts.el index bb7e5bea6e..c361609e0f 100644 --- a/lisp/progmodes/cc-fonts.el +++ b/lisp/progmodes/cc-fonts.el @@ -2579,6 +2579,39 @@ objc-font-lock-keywords (setq objc-font-lock-extra-types (cc-eval-when-compile (list (concat "[" c-upper "]\\sw*"))))) +\f +;;; Csharp. + +(c-override-default-keywords 'csharp-font-lock-keywords) + +(defconst csharp-font-lock-keywords-1 (c-lang-const c-matchers-1 csharp) + "Minimal font locking for C# mode. +Fontifies nothing except the syntactic fontification of strings and +comments.") + +(defconst csharp-font-lock-keywords-2 (c-lang-const c-matchers-2 csharp) + "Fast normal font locking for C# mode. +In addition to `csharp-font-lock-keywords-1', this adds fontification of +keywords, simple types, declarations that are easy to recognize, the +user defined types on `csharp-font-lock-extra-types', and the doc +comment styles specified by `c-doc-comment-style'.") + +(defconst csharp-font-lock-keywords-3 (c-lang-const c-matchers-3 csharp) + "Accurate normal font locking for C# mode. +Like variable `csharp-font-lock-keywords-2' but detects declarations in a more +accurate way that works in most cases for arbitrary types without the +need for `csharp-font-lock-extra-types'.") + +(defvar csharp-font-lock-keywords csharp-font-lock-keywords-3 + "Default expressions to highlight in C# mode.") + +(defun csharp-font-lock-keywords-2 () + (c-compose-keywords-list csharp-font-lock-keywords-2)) +(defun csharp-font-lock-keywords-3 () + (c-compose-keywords-list csharp-font-lock-keywords-3)) +(defun csharp-font-lock-keywords () + (c-compose-keywords-list csharp-font-lock-keywords)) + \f ;;; Java. diff --git a/lisp/progmodes/cc-langs.el b/lisp/progmodes/cc-langs.el index 13e70a3251..e6c314b445 100644 --- a/lisp/progmodes/cc-langs.el +++ b/lisp/progmodes/cc-langs.el @@ -378,7 +378,8 @@ c-make-mode-syntax-table (let ((table (make-syntax-table))) (c-populate-syntax-table table) ;; Mode specific syntaxes. - ,(cond ((or (c-major-mode-is 'objc-mode) (c-major-mode-is 'java-mode)) + ,(cond ((or (c-major-mode-is 'objc-mode) (c-major-mode-is 'java-mode) + (c-major-mode-is 'csharp-mode)) ;; Let '@' be part of symbols in ObjC to cope with ;; its compiler directives as single keyword tokens. ;; This is then necessary since it's assumed that @@ -430,7 +431,7 @@ c-identifier-syntax-modifications ;; it as an identifier character since it's often used in various ;; machine generated identifiers. t '((?_ . "w") (?$ . "w")) - (objc java) (append '((?@ . "w")) + (objc java csharp) (append '((?@ . "w")) (c-lang-const c-identifier-syntax-modifications)) awk '((?_ . "w"))) (c-lang-defvar c-identifier-syntax-modifications @@ -467,6 +468,9 @@ c-get-state-before-change-functions c-truncate-bs-cache c-before-change-check-unbalanced-strings c-parse-quotes-before-change) + csharp '(c-parse-quotes-before-change + c-before-change-check-unbalanced-strings + c-before-change-check-<>-operators) java '(c-parse-quotes-before-change c-before-change-check-unbalanced-strings c-before-change-check-<>-operators) @@ -516,6 +520,12 @@ c-before-font-lock-functions c-neutralize-syntax-in-CPP c-restore-<>-properties c-change-expand-fl-region) + csharp '(c-depropertize-new-text + c-after-change-escape-NL-in-string + c-parse-quotes-after-change + c-after-change-mark-abnormal-strings + c-restore-<>-properties + c-change-expand-fl-region) java '(c-depropertize-new-text c-after-change-escape-NL-in-string c-parse-quotes-after-change @@ -648,10 +658,11 @@ c-symbol-start "Regexp that matches the start of a symbol, i.e. any identifier or keyword. It's unspecified how far it matches. Does not contain a \\| operator at the top level." - t (concat "[" c-alpha "_]") - java (concat "[" c-alpha "_@]") - objc (concat "[" c-alpha "_@]") - pike (concat "[" c-alpha "_`]")) + t (concat "[" c-alpha "_]") + csharp (concat "[" c-alpha "_@]") + java (concat "[" c-alpha "_@]") + objc (concat "[" c-alpha "_@]") + pike (concat "[" c-alpha "_`]")) (c-lang-defvar c-symbol-start (c-lang-const c-symbol-start)) (c-lang-defconst c-symbol-chars @@ -718,6 +729,7 @@ c-identifier-ops ;; naming conventions. We still define "." here to make ;; `c-forward-name' move over as long names as possible which is ;; necessary to e.g. handle throws clauses correctly. + csharp '((left-assoc ".")) java '((left-assoc ".")) idl '((left-assoc "::") (prefix "::")) @@ -1247,6 +1259,8 @@ c-overloadable-operators "<<" ">>" ">>=" "<<=" "==" "!=" "not_eq" "<=" ">=" "&&" "and" "||" "??!??!" "or" "++" "--" "," "->*" "->" "()" "[]" "<::>" "??(??)") + csharp '("+" "-" "*" "/" "%" "&" "|" "^" "<<" ">>" "==" + "!=" ">" "<" ">=" "<=") ;; These work like identifiers in Pike. pike '("`+" "`-" "`&" "`|" "`^" "`<<" "`>>" "`*" "`/" "`%" "`~" "`==" "`<" "`>" "`!" "`[]" "`[]=" "`->" "`->=" "`()" "``+" @@ -2023,6 +2037,8 @@ c-primitive-type-kwds objc (append '("id" "Class" "SEL" "IMP" "BOOL") (c-lang-const c-primitive-type-kwds)) + csharp '("bool" "byte" "sbyte" "char" "decimal" "double" "float" "int" "uint" + "long" "ulong" "short" "ushort" "void" "object" "string" "var") java '("boolean" "byte" "char" "double" "float" "int" "long" "short" "void") idl '("Object" "ValueBase" "any" "boolean" "char" "double" "fixed" "float" "long" "octet" "sequence" "short" "string" "void" "wchar" "wstring" @@ -2137,7 +2153,8 @@ c-type-modifier-kwds on `c-primitive-type-kwds', they are fontified with the keyword face and not the type face." t (c-lang-const c-type-modifier-prefix-kwds) - c++ (append (c-lang-const c-type-modifier-prefix-kwds) '("throw"))) + c++ (append (c-lang-const c-type-modifier-prefix-kwds) '("throw")) + csharp '("readonly" "const" "volatile" "new")) (c-lang-defconst c-opt-type-modifier-key ;; Adorned regexp matching `c-type-modifier-kwds', or nil in @@ -2229,8 +2246,9 @@ c-brace-list-decl-kwds `c-colon-type-list-kwds', `c-paren-nontype-kwds', `c-paren-type-kwds', `c-<>-type-kwds', or `c-<>-arglist-kwds' then the associated clauses will be handled." - t '("enum") - (awk) nil) + t '("enum") + csharp '("enum" "new") + (awk) nil) (c-lang-defconst c-brace-list-key ;; Regexp matching the start of declarations where the following @@ -2281,6 +2299,7 @@ c-other-block-decl-kwds t nil (c objc) '("extern") c++ '("namespace" "extern") + csharp '("namespace") idl '("module" ;; In CORBA CIDL: "composition")) @@ -2341,7 +2360,8 @@ c-typedef-decl-key (c-lang-defconst c-using-kwds "Keywords which behave like `using' in C++" t nil - c++ '("using")) + c++ '("using") + csharp '("using")) (c-lang-defconst c-using-key ;; Regexp matching C++'s `using'. @@ -2410,6 +2430,10 @@ c-modifier-kwds "primary" "state" ;; In CORBA CIDL: "bindsTo" "delegatesTo" "implements" "proxy" "storedOn") + csharp '("abstract" "const" "default" "final" "native" "private" "protected" + "public" "partial" "internal" "readonly" "static" "event" "transient" + "volatile" "sealed" "ref" "out" "virtual" "implicit" "explicit" + "fixed" "override" "params" "async" "extern" "unsafe") ;; Note: "const" is not used in Java, but it's still a reserved keyword. java '("abstract" "const" "default" "final" "native" "private" "protected" "public" "static" "strictfp" "synchronized" "transient" "volatile") @@ -2634,14 +2658,16 @@ c-type-list-kwds Note: Use `c-typeless-decl-kwds' for keywords followed by a function or variable identifier (that's being defined)." - t nil - c++ '("operator") - objc '("@class") - java '("import" "new" "extends" "super" "implements" "throws") - idl '("manages" "native" "primarykey" "supports" - ;; In CORBA PSDL: - "as" "implements" "of" "scope") - pike '("inherit")) + t nil + c++ '("operator") + objc '("@class") + csharp '("struct" "class" "interface" "delegate" "event" "get" "set" "add" + "remove" "is" "as" "operator") + java '("import" "new" "extends" "super" "implements" "throws") + idl '("manages" "native" "primarykey" "supports" + ;; In CORBA PSDL: + "as" "implements" "of" "scope") + pike '("inherit")) (c-lang-defconst c-ref-list-kwds "Keywords that may be followed by a comma separated list of @@ -2652,24 +2678,25 @@ c-ref-list-kwds Note: Use `c-typeless-decl-kwds' for keywords followed by a function or variable identifier (that's being defined)." - t nil - c++ '("namespace") - java '("package") - idl '("import" "module" - ;; In CORBA CIDL: - "composition") - pike '("import")) + t nil + c++ '("namespace") + java '("package") + idl '("import" "module" + ;; In CORBA CIDL: + "composition") + pike '("import")) (c-lang-defconst c-colon-type-list-kwds "Keywords that may be followed (not necessarily directly) by a colon and then a comma separated list of type identifiers, where each optionally can be prefixed by keywords. (Can also be used for the special case when the list can contain only one element.)" - t nil - c++ '("class" "struct") - idl '("component" "eventtype" "home" "interface" "valuetype" - ;; In CORBA PSDL: - "storagehome" "storagetype")) + t nil + c++ '("class" "struct") + csharp '("class" "struct" "interface") + idl '("component" "eventtype" "home" "interface" "valuetype" + ;; In CORBA PSDL: + "storagehome" "storagetype")) (c-lang-defconst c-colon-type-list-re "Regexp matched after the keywords in `c-colon-type-list-kwds' to skip @@ -2765,11 +2792,12 @@ c-brace-id-list-kwds (c-lang-defconst c-block-stmt-1-kwds "Statement keywords followed directly by a substatement." - t '("do" "else") - c++ '("do" "else" "try") - objc '("do" "else" "@finally" "@try" "@autoreleasepool") - java '("do" "else" "finally" "try") - idl nil) + t '("do" "else") + c++ '("do" "else" "try") + objc '("do" "else" "@finally" "@try" "@autoreleasepool") + csharp '("do" "else" "finally" "try") + java '("do" "else" "finally" "try") + idl nil) (c-lang-defconst c-block-stmt-1-key ;; Regexp matching the start of any statement followed directly by a @@ -2781,7 +2809,8 @@ c-block-stmt-1-2-kwds "Statement keywords optionally followed by a paren sexp. Keywords here should also be in `c-block-stmt-1-kwds'." t nil - java '("try")) + csharp '("try") + java '("try")) (c-lang-defconst c-block-stmt-1-2-key ;; Regexp matching the start of a statement which may be followed by a @@ -2791,13 +2820,15 @@ c-block-stmt-1-2-key (c-lang-defconst c-block-stmt-2-kwds "Statement keywords followed by a paren sexp and then by a substatement." - t '("for" "if" "switch" "while") - c++ '("for" "if" "switch" "while" "catch") - objc '("for" "if" "switch" "while" "@catch" "@synchronized") - java '("for" "if" "switch" "while" "catch" "synchronized") - idl nil - pike '("for" "if" "switch" "while" "foreach") - awk '("for" "if" "switch" "while")) + t '("for" "if" "switch" "while") + c++ '("for" "if" "switch" "while" "catch") + objc '("for" "if" "switch" "while" "@catch" "@synchronized") + csharp '("for" "if" "switch" "while" "catch" "foreach" "fixed" "checked" + "unchecked" "using" "lock") + java '("for" "if" "switch" "while" "catch" "synchronized") + idl nil + pike '("for" "if" "switch" "while" "foreach") + awk '("for" "if" "switch" "while")) (c-lang-defconst c-block-stmt-2-key ;; Regexp matching the start of any statement followed by a paren sexp @@ -2838,6 +2869,7 @@ c-simple-stmt-kwds t '("break" "continue" "goto" "return") c++ '("break" "continue" "goto" "return" "co_return") objc '("break" "continue" "goto" "return" "@throw") + csharp '("break" "continue" "goto" "return" "throw") ;; Note: `goto' is not valid in Java, but the keyword is still reserved. java '("break" "continue" "goto" "return" "throw") idl nil @@ -2912,16 +2944,18 @@ c-constant-kwds objc '("nil" "Nil" "YES" "NO" "IBAction" "IBOutlet" "NS_DURING" "NS_HANDLER" "NS_ENDHANDLER") idl '("TRUE" "FALSE") + csharp '("true" "false" "null" "value") java '("true" "false" "null") ; technically "literals", not keywords pike '("UNDEFINED")) ;; Not a keyword, but practically works as one. (c-lang-defconst c-primary-expr-kwds "Keywords besides constants and operators that start primary expressions." - t nil - c++ '("operator" "this") - objc '("super" "self") - java '("this") - pike '("this")) ;; Not really a keyword, but practically works as one. + t nil + c++ '("operator" "this") + objc '("super" "self") + csharp '("this" "base" "operator") + java '("this") + pike '("this")) ;; Not really a keyword, but practically works as one. (c-lang-defconst c-expr-kwds ;; Keywords that can occur anywhere in expressions. Built from @@ -2948,16 +2982,18 @@ c-inexpr-block-kwds (c-lang-defconst c-inexpr-class-kwds "Keywords that can start classes inside expressions." - t nil - java '("new") - pike '("class")) + t nil + csharp '("new") + java '("new") + pike '("class")) (c-lang-defconst c-inexpr-brace-list-kwds "Keywords that can start brace list blocks inside expressions. Note that Java specific rules are currently applied to tell this from `c-inexpr-class-kwds'." - t nil - java '("new")) + t nil + csharp '("new") + java '("new")) (c-lang-defconst c-opt-inexpr-brace-list-key ;; Regexp matching the start of a brace list in an expression, or @@ -3049,6 +3085,7 @@ c-std-abbrev-keywords "List of keywords which may need to cause electric indentation." t '("else" "while") c++ (append (c-lang-const c-std-abbrev-keywords) '("catch")) + csharp (append (c-lang-const c-std-abbrev-keywords) '("catch" "finally")) java (append (c-lang-const c-std-abbrev-keywords) '("catch" "finally")) idl nil) (c-lang-defvar c-std-abbrev-keywords (c-lang-const c-std-abbrev-keywords)) @@ -3274,6 +3311,7 @@ c-decl-prefix-re ;; in all languages except Java for when a cpp macro definition ;; begins with a declaration. t "\\([{}();,]+\\)" + csharp "\\([{}(;,<]+\\)" java "\\([{}(;,<]+\\)" ;; Match "<" in C++ to get the first argument in a template arglist. ;; In that case there's an additional check in `c-find-decl-spots' @@ -3585,6 +3623,7 @@ c-opt-type-suffix-key is in effect or not." t nil (c c++ objc pike) "\\(\\.\\.\\.\\)" + csharp (concat "\\(\\[" (c-lang-const c-simple-ws) "*\\]\\|\\.\\.\\.\\)") java (concat "\\(\\[" (c-lang-const c-simple-ws) "*\\]\\|\\.\\.\\.\\)")) (c-lang-defvar c-opt-type-suffix-key (c-lang-const c-opt-type-suffix-key)) @@ -3644,7 +3683,7 @@ c-recognize-typeless-decls that are preceded by a declaration starting keyword, so e.g. `c-typeless-decl-kwds' may still be used when it's set to nil." t nil - (c c++ objc java) t) + (c c++ objc csharp java) t) (c-lang-defvar c-recognize-typeless-decls (c-lang-const c-recognize-typeless-decls)) @@ -3657,6 +3696,7 @@ c-recognize-<>-arglists expression is considered to be a type." t (or (consp (c-lang-const c-<>-type-kwds)) (consp (c-lang-const c-<>-arglist-kwds))) + csharp t java t) ; 2008-10-19. This is crude. The syntax for java ; generics is not yet coded in CC Mode. (c-lang-defvar c-recognize-<>-arglists (c-lang-const c-recognize-<>-arglists)) diff --git a/lisp/progmodes/cc-mode.el b/lisp/progmodes/cc-mode.el index c6dd671051..56cc476fad 100644 --- a/lisp/progmodes/cc-mode.el +++ b/lisp/progmodes/cc-mode.el @@ -36,12 +36,12 @@ ;; Note: The version string is in cc-defs. ;; This package provides GNU Emacs major modes for editing C, C++, -;; Objective-C, Java, CORBA's IDL, Pike and AWK code. As of the +;; Objective-C, C#, Java, CORBA's IDL, Pike and AWK code. As of the ;; latest Emacs and XEmacs releases, it is the default package for ;; editing these languages. This package is called "CC Mode", and ;; should be spelled exactly this way. -;; CC Mode supports K&R and ANSI C, ANSI C++, Objective-C, Java, +;; CC Mode supports K&R and ANSI C, ANSI C++, Objective-C, C#, Java, ;; CORBA's IDL, Pike and AWK with a consistent indentation model ;; across all modes. This indentation model is intuitive and very ;; flexible, so that almost any desired style of indentation can be @@ -75,7 +75,6 @@ ;; Externally maintained major modes which use CC-mode's engine include: ;; - cuda-mode -;; - csharp-mode (https://github.com/josteink/csharp-mode) ;; - haxe-mode ;; - d-mode ;; - dart-mode @@ -195,13 +194,14 @@ c-init-language-vars-for `c-init-language-vars' macro if the language you want to use is one of those, rather than a derived language defined through the language variable system (see \"cc-langs.el\")." - (cond ((eq mode 'c-mode) (c-init-language-vars c-mode)) - ((eq mode 'c++-mode) (c-init-language-vars c++-mode)) - ((eq mode 'objc-mode) (c-init-language-vars objc-mode)) - ((eq mode 'java-mode) (c-init-language-vars java-mode)) - ((eq mode 'idl-mode) (c-init-language-vars idl-mode)) - ((eq mode 'pike-mode) (c-init-language-vars pike-mode)) - ((eq mode 'awk-mode) (c-init-language-vars awk-mode)) + (cond ((eq mode 'c-mode) (c-init-language-vars c-mode)) + ((eq mode 'c++-mode) (c-init-language-vars c++-mode)) + ((eq mode 'objc-mode) (c-init-language-vars objc-mode)) + ((eq mode 'csharp-mode) (c-init-language-vars csharp-mode)) + ((eq mode 'java-mode) (c-init-language-vars java-mode)) + ((eq mode 'idl-mode) (c-init-language-vars idl-mode)) + ((eq mode 'pike-mode) (c-init-language-vars pike-mode)) + ((eq mode 'awk-mode) (c-init-language-vars awk-mode)) (t (error "Unsupported mode %s" mode)))) ;;;###autoload @@ -649,7 +649,8 @@ c-basic-common-init (when (or c-recognize-<>-arglists (c-major-mode-is 'awk-mode) - (c-major-mode-is '(java-mode c-mode c++-mode objc-mode pike-mode))) + (c-major-mode-is + '(java-mode c-mode c++-mode objc-mode pike-mode csharp-mode))) ;; We'll use the syntax-table text property to change the syntax ;; of some chars for this language, so do the necessary setup for ;; that. @@ -2739,6 +2740,48 @@ objc-mode (cc-imenu-init nil 'cc-imenu-objc-function) (c-run-mode-hooks 'c-mode-common-hook)) +\f +;; Support for C# + +(defvar csharp-mode-syntax-table + (funcall (c-lang-const c-make-mode-syntax-table csharp)) + "Syntax table used in csharp-mode buffers.") + +(defvar csharp-mode-map + (let ((map (c-make-inherited-keymap))) + map) + "Keymap used in csharp-mode buffers.") +;; Add bindings which are only useful for C#. + +(easy-menu-define c-csharp-menu csharp-mode-map "C# Mode Commands" + (cons "C#" (c-lang-const c-mode-menu csharp))) + +;;;###autoload (add-to-list 'auto-mode-alist '("\\.cs\\'" . csharp-mode)) + +;;;###autoload +(define-derived-mode csharp-mode prog-mode "C#" + "Major mode for editing Csharp code. +To submit a problem report, enter `\\[c-submit-bug-report]' from a +csharp-mode buffer. This automatically sets up a mail buffer with +version information already added. You just need to add a description +of the problem, including a reproducible test case, and send the +message. + +To see what version of CC Mode you are running, enter `\\[c-version]'. + +The hook `c-mode-common-hook' is run with no args at mode +initialization, then `csharp-mode-hook'. + +Key bindings: +\\{csharp-mode-map}" + :after-hook (c-update-modeline) + (c-initialize-cc-mode t) + (setq abbrev-mode t) + (c-init-language-vars-for 'csharp-mode) + (c-common-init 'csharp-mode) + (easy-menu-add c-csharp-menu) + (c-run-mode-hooks 'c-mode-common-hook)) + \f ;; Support for Java diff --git a/lisp/progmodes/cc-styles.el b/lisp/progmodes/cc-styles.el index 36be9f6c74..be025810a9 100644 --- a/lisp/progmodes/cc-styles.el +++ b/lisp/progmodes/cc-styles.el @@ -215,6 +215,42 @@ c-style-alist (arglist-cont-nonempty))) (c-block-comment-prefix . "")) + ("csharp" + (c-basic-offset . 4) + (c-comment-only-line-offset . (0 . 0)) + (c-offsets-alist . ((inline-open . 0) + (topmost-intro . 0) + (topmost-intro-cont . 0) + (statement-block-intro . +) + (statement-case-intro . +) + (statement-case-open . +) + (substatement . 0) + (substatement-open . 0) + (substatement-label . +) + (label . 0) + (statement-case-open . +) + (statement-cont . 0) + (arglist-cont-nonempty . 0) + (inexpr-class . -) + (arglist-intro . c-lineup-arglist-intro-after-paren) + (arglist-close . c-lineup-arglist) + (string . c-lineup-dont-change) + (arglist-cont . 0) + (block-open . 0) + (block-close . 0) + (case-label . +) + (class-open . 0) + (class-close . 0) + (defun-open . 0) + (defun-close . 0) + (else-clause . 0) + (brace-list-intro . (first + c-lineup-class-decl-init-+ + + c-lineup-2nd-brace-entry-in-arglist)) + (brace-list-close . 0) + (access-label . -) + (inher-cont . c-lineup-java-inher) + (func-decl-cont . c-lineup-java-throws)))) ("java" (c-basic-offset . 4) (c-comment-only-line-offset . (0 . 0)) diff --git a/lisp/progmodes/cc-vars.el b/lisp/progmodes/cc-vars.el index 9e6f9527ca..559531fafe 100644 --- a/lisp/progmodes/cc-vars.el +++ b/lisp/progmodes/cc-vars.el @@ -549,6 +549,8 @@ c-comment-prefix-regexp (const :format "C++ " c++-mode) (regexp :format "%v")) (cons :format "%v" (const :format "ObjC " objc-mode) (regexp :format "%v")) + (cons :format "%v" + (const :format "C# " csharp-mode) (regexp :format "%v")) (cons :format "%v" (const :format "Java " java-mode) (regexp :format "%v")) (cons :format "%v" @@ -919,6 +921,9 @@ c-require-final-newline (cons :format "%v" (const :format "ObjC " objc-mode) (symbol :format "%v" :value ,require-final-newline)) + (cons :format "%v" + (const :format "C# " csharp-mode) + (symbol :format "%v" :value ,require-final-newline)) (cons :format "%v" (const :format "Java " java-mode) (symbol :format "%v" :value ,require-final-newline)) @@ -1003,6 +1008,7 @@ c-objc-method-parameter-offset :group 'c) (defcustom c-default-style '((java-mode . "java") (awk-mode . "awk") + (csharp-mode . "csharp") (other . "gnu")) "Style which gets installed by default when a file is visited. @@ -1031,6 +1037,8 @@ c-default-style (const :format "C++ " c++-mode) (string :format "%v")) (cons :format "%v" (const :format "ObjC " objc-mode) (string :format "%v")) + (cons :format "%v" + (const :format "C# " csharp-mode) (string :format "%v")) (cons :format "%v" (const :format "Java " java-mode) (string :format "%v")) (cons :format "%v" @@ -1459,6 +1467,11 @@ objc-mode-hook :type 'hook :group 'c) +(defcustom csharp-mode-hook nil + "Hook called by `csharp-mode'." + :type 'hook + :group 'c) + (defcustom java-mode-hook nil "Hook called by `java-mode'." :type 'hook @@ -1613,6 +1626,15 @@ objc-font-lock-extra-types :type 'c-extra-types-widget :group 'c) +(defcustom csharp-font-lock-extra-types + (list (concat "[" c-upper "]\\sw*[" c-lower "]\\sw")) + (c-make-font-lock-extra-types-blurb "C#" "csharp-mode" (concat +"For example, a value of (\"[" c-upper "]\\\\sw*[" c-lower "]\\\\sw*\") means +capitalized words are treated as type names (the requirement for a +lower case char is to avoid recognizing all-caps constant names).")) + :type 'c-extra-types-widget + :group 'c) + (defcustom java-font-lock-extra-types (list (concat "[" c-upper "]\\sw*[" c-lower "]\\sw")) (c-make-font-lock-extra-types-blurb "Java" "java-mode" (concat -- 2.28.0 ^ permalink raw reply related [flat|nested] 15+ messages in thread
* bug#43559: 28.0.50; [PATCH] Add csharp support to cc-mode 2020-09-22 21:15 ` Theodor Thornhill via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2020-09-23 8:46 ` Jostein Kjønigsen 0 siblings, 0 replies; 15+ messages in thread From: Jostein Kjønigsen @ 2020-09-23 8:46 UTC (permalink / raw) To: theo, 43559; +Cc: acm [-- Attachment #1: Type: text/plain, Size: 3194 bytes --] On 22.09.2020 23:15, Theodor Thornhill wrote: > > my most recent patch seems to deal with this (attributes) properly, as far > as I can tell. I've tested with your example code and also with random > files in the roslyn repository. Fontification is still sparse here. Basic attribute-indentation is confirmed fixed on my end. Still no fontification, but I don't think that's critical. > >> *Second: Object initializers are not indented properly.* > This one should be fixed in the attached patch. It's better, but not quite there. For a simple 1-level nested object-initializer, the line containing the closing bracket is still incorrectly indented: > > I think the recursion case works as well. I've made an attempt in the > attached 'test.cs' I can't reproduce this. Are you sure the attached patch contains all your changes? Looking at your example, your sub-initializer is actually a /collection /initializer, which may explain why it seemingly worked on your end. > > This (lambdas) one should be fixed in the latest patch. Confirmed fixed on my end. >> *Fourth: variable-fontification* >> >> Here I have no absolute C# convention to quote for absolute correctness, >> but it kinda "feels wrong" to me at places. >> So we'll have to make due with imperfections, make some pragmatical >> decisions on what we think will be good default/fallback values, and >> that's OK. >> > Agreed > >> Right now though, all implicitly typed variables (vars), local variables >> with method-access and local fields with property-access are shown using >> /font-lock-constant-face/ and that seems a bit off: > This case is fixed now. It was due to the 'var' keyword was put in the > wrong basket. Confirmed fixed. This change alone makes things look much better. In the process of testing this, I've also taken a look at some other keywords: const, string, bool, int, async and await. From what I can tell, they all look proper except for "await". Looking in the patch, I see it's not mentioned there, so it should probably be a quick fix though? Looking at faces more in depth, I also see annotated functions are not getting their function-names fontified. I guess this goes back to the overall complexity of the attribute-store and core cc-mode support? > >> As for "_field" and "foo.", I'm not sure what the best fallback would >> be. Without a language-engine to guide us, this is genuinely hard stuff >> to get right. >> > Yeah, this one is kind of hard, so I've been ignoring it for a little > while. The easiest thing should be to remove the highlighting, but not > sure if that is the best move so far. I agree this is hard. Even trying to come up with some simple pragmatic rules, I'm constantly left thinking about "what ifs"... So we can leave it for now. As for your test-file, I see you've added a multi-line case with a ternary operator. That made me look into multi-line statements in general. It seems they are not getting indented as expected: Maybe if you figure out how to fix that, you will also fix the ternary-issue at the same time? -- Kind regards *Jostein Kjønigsen* jostein@kjonigsen.net 🍵 jostein@gmail.com https://jostein.kjønigsen.no [-- Attachment #2.1: Type: text/html, Size: 5788 bytes --] [-- Attachment #2.2: cbdccnkapbnidcfb.png --] [-- Type: image/png, Size: 5798 bytes --] [-- Attachment #2.3: dadgfepfdgfigdjo.png --] [-- Type: image/png, Size: 9718 bytes --] [-- Attachment #2.4: kgdddfodhnglljmd.png --] [-- Type: image/png, Size: 8819 bytes --] [-- Attachment #2.5: oclbllokmkogdccb.png --] [-- Type: image/png, Size: 11134 bytes --] [-- Attachment #2.6: nhalblonfacnkbej.png --] [-- Type: image/png, Size: 4844 bytes --] ^ permalink raw reply [flat|nested] 15+ messages in thread
* bug#43559: 28.0.50; [PATCH] Add csharp support to cc-mode 2020-09-22 10:37 bug#43559: 28.0.50; [PATCH] Add csharp support to cc-mode Theodor Thornhill via Bug reports for GNU Emacs, the Swiss army knife of text editors 2020-09-22 12:51 ` Jostein Kjønigsen @ 2020-09-23 10:11 ` Alan Mackenzie 2020-09-23 18:38 ` Theodor Thornhill via Bug reports for GNU Emacs, the Swiss army knife of text editors 2020-09-28 19:52 ` Theodor Thornhill via Bug reports for GNU Emacs, the Swiss army knife of text editors 1 sibling, 2 replies; 15+ messages in thread From: Alan Mackenzie @ 2020-09-23 10:11 UTC (permalink / raw) To: Theodor Thornhill; +Cc: 43559, jostein Hello, Theodor. On Tue, Sep 22, 2020 at 12:37:54 +0200, Theodor Thornhill wrote: > Hello! > For some time, I've been a little dissatisfied with the support for C# > in emacs. Recently, there has been some breakage in handling of strings > and fontification, more precisely: > - https://github.com/josteink/csharp-mode/issues/128 The current C# mode uses syntax-propertize-function. This clashes nastily with CC Mode's use of the syntax-table text property. When syntax-propertize-function is non-nil, Emacs arbitrarily wipes all syntax-table properties from a region then relies on s-p-f to reapply all the necessary s-t properties. However the current C# s-p-f only applies a restricted subset of the necessary properties. This will produce random bugs. The documentation for syntax-propertize-function didn't used to mention this problem, but it does now. (As from Emacs 27.2). The method used in CC Mode to apply and remove these properties is to add functions, effectively before- or after-change-functions, to either or both of c-get-state-before-change-functions and c-before-font-lock-functions. > Also, it is using a lot of internal c-mode functions: > - https://github.com/josteink/csharp-mode/issues/153 > I've had some discussions with with the current maintainer, Jostein > Kjønigsen (cc'd) about the future of this mode in > https://github.com/josteink/csharp-mode/issues/162. > Some points of note: > - It cannot easily be donated to emacs due to paperwork > - Jostein does not have time to do it himself > - I took upon myself to rewrite it in a separate branch, as an end > goal for it to be included in emacs > While working on this, I realized the easiest way to get something good > here is to overall reduce the complexity. As such I created this patch. CC Mode places a high priority on correctness, hence much of its complexity. That priority needn't necessarily be carried over to derived modes. ;-) > It seems to work nicely, removing the need for the external mode > completely. You're proposing integrating a new C# Mode directly into CC Mode. This goes against CC Mode policy, both because it would swell the already massive code base, and it would increases the danger of "orphan" submodes. We already have IDL Mode and Pike Mode which have remained entirely and almost entirely unchanged in the last 15 years. The people who created them are no longer around. Also, there is no advantage for an integrated mode over a derived mode separate from CC Mode. (If there is, that is a bug in CC Mode. ;-) There is a slight effort in using c-add-language, that is all. > However, I see that including csharp here is most likely a bigger effort > than just sending this patch, but I wanted to send what I have, and > hopefully get some pointers. Or in worst case stop before I go too > far.. I don't see a reason why there shouldn't be a C# Mode directly in Emacs. > This patch is written without consulting the current mode, so paperwork > should not be an issue. > In addition, the current mode has an implementation of imenu rewritten > from scratch by Jostein, and as such I think this can be included as > well. > I tried not to do too much, since I believe most of the advanced > functionality should be provided by an lsp mode such as eglot or lsp-mode. That is a completely different topic. The amount of work needed to use one of these is massive. For what it's worth, somebody familiar with LSPs opined that they weren't yet sufficiently mature to support something like CC Mode, but this was some while ago (between 1 and 2 years ago). > Have a nice day! > Theodor Thornhill [ Patch snipped, but briefly scanned. ] -- Alan Mackenzie (Nuremberg, Germany). ^ permalink raw reply [flat|nested] 15+ messages in thread
* bug#43559: 28.0.50; [PATCH] Add csharp support to cc-mode 2020-09-23 10:11 ` Alan Mackenzie @ 2020-09-23 18:38 ` Theodor Thornhill via Bug reports for GNU Emacs, the Swiss army knife of text editors 2020-09-28 19:52 ` Theodor Thornhill via Bug reports for GNU Emacs, the Swiss army knife of text editors 1 sibling, 0 replies; 15+ messages in thread From: Theodor Thornhill via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2020-09-23 18:38 UTC (permalink / raw) To: Alan Mackenzie; +Cc: 43559, jostein Alan Mackenzie <acm@muc.de> writes: > Hello, Theodor. > Hello, and thanks for responding! > On Tue, Sep 22, 2020 at 12:37:54 +0200, Theodor Thornhill wrote: > > >> Hello! > >> For some time, I've been a little dissatisfied with the support for C# >> in emacs. Recently, there has been some breakage in handling of strings >> and fontification, more precisely: > >> - https://github.com/josteink/csharp-mode/issues/128 > > The current C# mode uses syntax-propertize-function. This clashes > nastily with CC Mode's use of the syntax-table text property. When > syntax-propertize-function is non-nil, Emacs arbitrarily wipes all > syntax-table properties from a region then relies on s-p-f to reapply > all the necessary s-t properties. However the current C# s-p-f only > applies a restricted subset of the necessary properties. This will > produce random bugs. Thanks for this information. It will help me investigate further. > > The documentation for syntax-propertize-function didn't used to mention > this problem, but it does now. (As from Emacs 27.2). > > The method used in CC Mode to apply and remove these properties is to > add functions, effectively before- or after-change-functions, to either > or both of c-get-state-before-change-functions and > c-before-font-lock-functions. > [...] >> While working on this, I realized the easiest way to get something good >> here is to overall reduce the complexity. As such I created this patch. > > CC Mode places a high priority on correctness, hence much of its > complexity. That priority needn't necessarily be carried over to > derived modes. ;-) > Hehe, yeah - it is my hope to leverage more what is already there. >> It seems to work nicely, removing the need for the external mode >> completely. > > You're proposing integrating a new C# Mode directly into CC Mode. This > goes against CC Mode policy, both because it would swell the already > massive code base, and it would increases the danger of "orphan" > submodes. We already have IDL Mode and Pike Mode which have remained > entirely and almost entirely unchanged in the last 15 years. The people > who created them are no longer around. I see your point here. I guess I wrongly assumed this should be the main way to include new cc-mode based modes. > > Also, there is no advantage for an integrated mode over a derived mode > separate from CC Mode. (If there is, that is a bug in CC Mode. ;-) > There is a slight effort in using c-add-language, that is all. > That is good to hear. I guess I'll try to reimplement this patch using this api, rather than convince you to pollute CC Mode. >> However, I see that including csharp here is most likely a bigger effort >> than just sending this patch, but I wanted to send what I have, and >> hopefully get some pointers. Or in worst case stop before I go too >> far.. > > I don't see a reason why there shouldn't be a C# Mode directly in Emacs. > Good. I'll start working on csharp-mode.el, rather than integrating things. >> This patch is written without consulting the current mode, so paperwork >> should not be an issue. > >> In addition, the current mode has an implementation of imenu rewritten >> from scratch by Jostein, and as such I think this can be included as >> well. > >> I tried not to do too much, since I believe most of the advanced >> functionality should be provided by an lsp mode such as eglot or lsp-mode. > > That is a completely different topic. The amount of work needed to use > one of these is massive. For what it's worth, somebody familiar with > LSPs opined that they weren't yet sufficiently mature to support > something like CC Mode, but this was some while ago (between 1 and 2 > years ago). Yeah, I wasn't really suggesting to integrate CC Mode with eglot. I was merely commenting on reducing the scope of this potential mode. Thanks for taking your time so far. I think I'll for the time being leave this bug, take it back to github, and create a standalone mode. (@Jostein - I'll respond to your comments on GitHub) Have a nice day/evening, -- Theodor Thornhill ^ permalink raw reply [flat|nested] 15+ messages in thread
* bug#43559: 28.0.50; [PATCH] Add csharp support to cc-mode 2020-09-23 10:11 ` Alan Mackenzie 2020-09-23 18:38 ` Theodor Thornhill via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2020-09-28 19:52 ` Theodor Thornhill via Bug reports for GNU Emacs, the Swiss army knife of text editors 2021-07-21 12:19 ` Lars Ingebrigtsen 1 sibling, 1 reply; 15+ messages in thread From: Theodor Thornhill via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2020-09-28 19:52 UTC (permalink / raw) To: Alan Mackenzie; +Cc: 43559, jostein Hello, Alan! Alan Mackenzie <acm@muc.de> writes: [...] > > I don't see a reason why there shouldn't be a C# Mode directly in Emacs. > The current csharp mode is now rewritten, and I've gotten almost everything to work nicely apart from one issue, and I was hoping that you could help me figure it out, or point me in the right direction. I described it here: https://lists.gnu.org/archive/html/emacs-devel/2020-09/msg01975.html However, The lambda case is now fixed, but with a patch to emacs itself: -------------------------------------------------------------------------------- diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el index 4e336c0a06..b415e4b821 100644 --- a/lisp/progmodes/cc-engine.el +++ b/lisp/progmodes/cc-engine.el @@ -12011,7 +12011,8 @@ c-looking-at-inexpr-block (> (point) closest-lim)) (not (bobp)) (progn (backward-char) - (looking-at "[]).]\\|\\w\\|\\s_")) + (or (looking-at "[\]\).]\\|\w\\|\\s_") + (looking-at ">"))) (c-safe (forward-char) (goto-char (scan-sexps (point) -1)))) @@ -12085,7 +12086,11 @@ c-looking-at-inexpr-block (setq passed-bracket-pairs 1) (setq bracket-pos (point)))) 'maybe) - 'maybe)))) + 'maybe) + (if (or (looking-at "([[:alnum:][:space:]_,]*)[ \t\n]*=>[ \t\n]*{") + (looking-at "[[:alnum:]_]+[ \t\n]*=>[ \t\n]*{")) + ;; If we are at a C# lambda header + (cons 'inexpr (point)))))) (if (eq res 'maybe) (cond -------------------------------------------------------------------------------- This patch lets CC Mode detect the lambda case for C#. I know this is a patch specific to C#, but I could not find anywhere or anyhow this would work without these lines. With them, the indentation in case 1 in the mentioned link works perfectly. Maybe this (or something similar) could be eligible for inclusion in CC Mode, to account for that lambda syntax. I know many other C-like languages uses similar syntax, so I believe it could be useful for someone else as well. Have a nice evening! -- Theodor Thornhill ^ permalink raw reply related [flat|nested] 15+ messages in thread
* bug#43559: 28.0.50; [PATCH] Add csharp support to cc-mode 2020-09-28 19:52 ` Theodor Thornhill via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2021-07-21 12:19 ` Lars Ingebrigtsen 2021-07-21 12:36 ` Theodor Thornhill via Bug reports for GNU Emacs, the Swiss army knife of text editors 0 siblings, 1 reply; 15+ messages in thread From: Lars Ingebrigtsen @ 2021-07-21 12:19 UTC (permalink / raw) To: Theodor Thornhill; +Cc: Alan Mackenzie, jostein, Stefan Monnier, 43559 Theodor Thornhill <theo@thornhill.no> writes: >> I don't see a reason why there shouldn't be a C# Mode directly in Emacs. > > The current csharp mode is now rewritten, Great! Including it in GNU ELPA would be cool. Stefan? > However, The lambda case is now fixed, but with a patch to emacs > itself: > > -------------------------------------------------------------------------------- > diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el > index 4e336c0a06..b415e4b821 100644 > --- a/lisp/progmodes/cc-engine.el > +++ b/lisp/progmodes/cc-engine.el Alan, would it be OK to include that small change in cc-engine? -- (domestic pets only, the antidote for overdose, milk.) bloggy blog: http://lars.ingebrigtsen.no ^ permalink raw reply [flat|nested] 15+ messages in thread
* bug#43559: 28.0.50; [PATCH] Add csharp support to cc-mode 2021-07-21 12:19 ` Lars Ingebrigtsen @ 2021-07-21 12:36 ` Theodor Thornhill via Bug reports for GNU Emacs, the Swiss army knife of text editors 2021-07-21 12:58 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 0 siblings, 1 reply; 15+ messages in thread From: Theodor Thornhill via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2021-07-21 12:36 UTC (permalink / raw) To: Lars Ingebrigtsen; +Cc: Alan Mackenzie, jostein, Stefan Monnier, 43559 [-- Attachment #1: Type: text/html, Size: 2973 bytes --] ^ permalink raw reply [flat|nested] 15+ messages in thread
* bug#43559: 28.0.50; [PATCH] Add csharp support to cc-mode 2021-07-21 12:36 ` Theodor Thornhill via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2021-07-21 12:58 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 2021-07-21 13:18 ` Theodor Thornhill via Bug reports for GNU Emacs, the Swiss army knife of text editors 2021-07-21 14:05 ` Jostein Kjønigsen 0 siblings, 2 replies; 15+ messages in thread From: Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2021-07-21 12:58 UTC (permalink / raw) To: Theodor Thornhill; +Cc: Alan Mackenzie, Lars Ingebrigtsen, jostein, 43559 > > Great! Including it in GNU ELPA would be cool. Stefan? Fine by me. > Right now it lives in melpa, but there is no particular reason for it > not to be in elpa/Emacs by default. Excellent. > There are some performance issues that are being addressed by Alan > with regards to multiline strings. That should have no bearing on inclusion into GNU ELPA. > The paperwork should be very easy, as I _think_ the only people with > commits that needs paperwork is Jostein and me. Can you double check? Stefan ^ permalink raw reply [flat|nested] 15+ messages in thread
* bug#43559: 28.0.50; [PATCH] Add csharp support to cc-mode 2021-07-21 12:58 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2021-07-21 13:18 ` Theodor Thornhill via Bug reports for GNU Emacs, the Swiss army knife of text editors [not found] ` <jwvim13zo90.fsf-monnier+emacs@gnu.org> 2021-07-21 14:05 ` Jostein Kjønigsen 1 sibling, 1 reply; 15+ messages in thread From: Theodor Thornhill via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2021-07-21 13:18 UTC (permalink / raw) To: Stefan Monnier; +Cc: Alan Mackenzie, Lars Ingebrigtsen, jostein, 43559 Stefan Monnier <monnier@iro.umontreal.ca> writes: >> > Great! Including it in GNU ELPA would be cool. Stefan? > > Fine by me. > Cool! >> There are some performance issues that are being addressed by Alan >> with regards to multiline strings. > > That should have no bearing on inclusion into GNU ELPA. No, I assume it should be even easier to change csharp-mode when those fixes arrive. > >> The paperwork should be very easy, as I _think_ the only people with >> commits that needs paperwork is Jostein and me. > > Can you double check? > I'm not completely sure how I'd double check that for there to be no issues at all legally. When I did the rewrite I did it without looking at the already existing code, since I wanted the option to include it in emacs at some point. If you look at https://github.com/emacs-csharp/csharp-mode/blame/master/csharp-mode.el you'll find that most commits are from me, except the header comments, which I took from the existing code. Most of the other commits that are referenced in that blame is either whitespace that didn't change when the new version was merged as well as some one line bug patches that came after the new version arrived. I assume they are ok to add to elpa, given their size? Other commits are ci related and an indentation fix. How do I verify this? Theo ^ permalink raw reply [flat|nested] 15+ messages in thread
[parent not found: <jwvim13zo90.fsf-monnier+emacs@gnu.org>]
[parent not found: <35791e76-b783-4856-a4e4-adf7996b5a45@www.fastmail.com>]
[parent not found: <jwv5yx3zisf.fsf-monnier+emacs@gnu.org>]
[parent not found: <jwvsg07y0jc.fsf-monnier+emacs@gnu.org>]
[parent not found: <m1a6mf4fs0.fsf@Frende-MacBook.lan>]
[parent not found: <jwvtuknwi87.fsf-monnier+emacs@gnu.org>]
[parent not found: <m17dhj4bwo.fsf@Frende-MacBook.lan>]
[parent not found: <jwvh7gkrcrw.fsf-monnier+emacs@gnu.org>]
[parent not found: <m1mtpcouwb.fsf@Frende-MacBook.lan>]
[parent not found: <jwveeamohsz.fsf-monnier+emacs@gnu.org>]
[parent not found: <325FA529-DED9-4061-8536-39168D18A504@thornhill.no>]
* bug#43559: 28.0.50; [PATCH] Add csharp support to cc-mode [not found] ` <325FA529-DED9-4061-8536-39168D18A504@thornhill.no> @ 2021-08-25 16:07 ` Lars Ingebrigtsen 0 siblings, 0 replies; 15+ messages in thread From: Lars Ingebrigtsen @ 2021-08-25 16:07 UTC (permalink / raw) To: Theodor Thornhill Cc: 43559, Jostein Kjønigsen, Stefan Monnier, Alan Mackenzie, jostein, jose.junior Theodor Thornhill <theo@thornhill.no> writes: > Seeing how this is how included to elpa I guess this issue can be closed :) > thanks for your patience! :-) I'm closing this issue, then. ^ permalink raw reply [flat|nested] 15+ messages in thread
* bug#43559: 28.0.50; [PATCH] Add csharp support to cc-mode 2021-07-21 12:58 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 2021-07-21 13:18 ` Theodor Thornhill via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2021-07-21 14:05 ` Jostein Kjønigsen 1 sibling, 0 replies; 15+ messages in thread From: Jostein Kjønigsen @ 2021-07-21 14:05 UTC (permalink / raw) To: Stefan Monnier, Theodor Thornhill Cc: Alan Mackenzie, Lars Ingebrigtsen, Jostein Kjønigsen, 43559 [-- Attachment #1: Type: text/plain, Size: 1007 bytes --] On vacation without a laptop, but just chiming in that I’ve previously done the required FSF copyright assignment. So any commits on my part should not lead to any additional paperwork. -- Vennlig hilsen Jostein Kjønigsen jostein@kjonigsen.net 🍵 jostein@gmail.com https://jostein.kjønigsen.no <https://jostein.xn--kjnigsen-64a.no/> On Wed, Jul 21, 2021, at 14:58, Stefan Monnier wrote: > > > Great! Including it in GNU ELPA would be cool. Stefan? > > Fine by me. > > > Right now it lives in melpa, but there is no particular reason for it > > not to be in elpa/Emacs by default. > > Excellent. > > > There are some performance issues that are being addressed by Alan > > with regards to multiline strings. > > That should have no bearing on inclusion into GNU ELPA. > > > The paperwork should be very easy, as I _think_ the only people with > > commits that needs paperwork is Jostein and me. > > Can you double check? > > > Stefan > > [-- Attachment #2: Type: text/html, Size: 1978 bytes --] ^ permalink raw reply [flat|nested] 15+ messages in thread
end of thread, other threads:[~2021-08-25 16:07 UTC | newest] Thread overview: 15+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2020-09-22 10:37 bug#43559: 28.0.50; [PATCH] Add csharp support to cc-mode Theodor Thornhill via Bug reports for GNU Emacs, the Swiss army knife of text editors 2020-09-22 12:51 ` Jostein Kjønigsen 2020-09-22 13:10 ` Theodor Thornhill via Bug reports for GNU Emacs, the Swiss army knife of text editors 2020-09-22 14:26 ` Jostein Kjønigsen 2020-09-22 21:15 ` Theodor Thornhill via Bug reports for GNU Emacs, the Swiss army knife of text editors 2020-09-23 8:46 ` Jostein Kjønigsen 2020-09-23 10:11 ` Alan Mackenzie 2020-09-23 18:38 ` Theodor Thornhill via Bug reports for GNU Emacs, the Swiss army knife of text editors 2020-09-28 19:52 ` Theodor Thornhill via Bug reports for GNU Emacs, the Swiss army knife of text editors 2021-07-21 12:19 ` Lars Ingebrigtsen 2021-07-21 12:36 ` Theodor Thornhill via Bug reports for GNU Emacs, the Swiss army knife of text editors 2021-07-21 12:58 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 2021-07-21 13:18 ` Theodor Thornhill via Bug reports for GNU Emacs, the Swiss army knife of text editors [not found] ` <jwvim13zo90.fsf-monnier+emacs@gnu.org> [not found] ` <35791e76-b783-4856-a4e4-adf7996b5a45@www.fastmail.com> [not found] ` <jwv5yx3zisf.fsf-monnier+emacs@gnu.org> [not found] ` <jwvsg07y0jc.fsf-monnier+emacs@gnu.org> [not found] ` <m1a6mf4fs0.fsf@Frende-MacBook.lan> [not found] ` <jwvtuknwi87.fsf-monnier+emacs@gnu.org> [not found] ` <m17dhj4bwo.fsf@Frende-MacBook.lan> [not found] ` <jwvh7gkrcrw.fsf-monnier+emacs@gnu.org> [not found] ` <m1mtpcouwb.fsf@Frende-MacBook.lan> [not found] ` <jwveeamohsz.fsf-monnier+emacs@gnu.org> [not found] ` <325FA529-DED9-4061-8536-39168D18A504@thornhill.no> 2021-08-25 16:07 ` Lars Ingebrigtsen 2021-07-21 14:05 ` Jostein Kjønigsen
Code repositories for project(s) associated with this external index https://git.savannah.gnu.org/cgit/emacs.git https://git.savannah.gnu.org/cgit/emacs/org-mode.git This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.