commit 463cd87f0590970cfd2918ba7028304e0f712001 (HEAD, refs/remotes/origin/master) Author: Wilhelm H Kirschbaum Date: Wed Nov 15 20:41:08 2023 +0200 Various improvements to font-lock-settings for elixir-ts-mode Changes and made from conversations from the Elixir slack channel, the github issue https://github.com/wkirschbaum/elixir-ts-mode/issues/35 and bug#67246. * lisp/progmodes/elixir-ts-mode.el (elixir-ts--font-lock-settings): Update features. (elixir-ts-mode): Update treesit-font-lock-feature-list. (elixir-ts-font-comment-doc-identifier-face): Rename to elixir-ts-comment-doc-identifier. (elixir-ts-font-comment-doc-attribute-face): Rename to elixir-ts-comment-doc-attribute. (elixir-ts-font-sigil-name-face): Rename to elixir-ts-sigil-name. (elixir-ts-atom-key-face) (elixir-ts-keyword-key-face) (elixir-ts-attribute-face): Add new custom face. diff --git a/lisp/progmodes/elixir-ts-mode.el b/lisp/progmodes/elixir-ts-mode.el index c687ed9d06b..62429308d96 100644 --- a/lisp/progmodes/elixir-ts-mode.el +++ b/lisp/progmodes/elixir-ts-mode.el @@ -86,17 +86,35 @@ elixir-ts-mode-hook :group 'elixir-ts :version "30.1") -(defface elixir-ts-font-comment-doc-identifier-face +(defface elixir-ts-comment-doc-identifier '((t (:inherit font-lock-doc-face))) - "Face used for @comment.doc tags in Elixir files.") + "Face used for doc identifiers in Elixir files." + :group 'elixir-ts) -(defface elixir-ts-font-comment-doc-attribute-face +(defface elixir-ts-comment-doc-attribute '((t (:inherit font-lock-doc-face))) - "Face used for @comment.doc.__attribute__ tags in Elixir files.") + "Face used for doc attributes in Elixir files." + :group 'elixir-ts) -(defface elixir-ts-font-sigil-name-face +(defface elixir-ts-sigil-name '((t (:inherit font-lock-string-face))) - "Face used for @__name__ tags in Elixir files.") + "Face used for sigils in Elixir files." + :group 'elixir-ts) + +(defface elixir-ts-atom + '((t (:inherit font-lock-constant-face))) + "Face used for atoms in Elixir files." + :group 'elixir-ts) + +(defface elixir-ts-keyword-key + '((t (:inherit elixir-ts-atom))) + "Face used for keyword keys in Elixir files." + :group 'elixir-ts) + +(defface elixir-ts-attribute + '((t (:inherit font-lock-preprocessor-face))) + "Face used for attributes in Elixir files." + :group 'elixir-ts) (defconst elixir-ts--sexp-regexp (rx bol @@ -114,7 +132,10 @@ elixir-ts--definition-keywords "defoverridable" "defp" "defprotocol" "defstruct")) (defconst elixir-ts--definition-keywords-re - (concat "^" (regexp-opt elixir-ts--definition-keywords) "$")) + (concat "^" (regexp-opt + (append elixir-ts--definition-keywords + elixir-ts--test-definition-keywords)) + "$")) (defconst elixir-ts--kernel-keywords '("alias" "case" "cond" "else" "for" "if" "import" "quote" @@ -334,56 +355,73 @@ elixir-ts--indent-rules (treesit-node-start (treesit-node-parent (treesit-node-at (point) 'elixir)))) - 0))))) + 0))))) (defvar elixir-ts--font-lock-settings (treesit-font-lock-rules :language 'elixir - :feature 'elixir-comment - '((comment) @font-lock-comment-face) - - :language 'elixir - :feature 'elixir-string - :override t - '([(string) (charlist)] @font-lock-string-face) - + :feature 'elixir-function-name + `((call target: (identifier) @target-identifier + (arguments (identifier) @font-lock-function-name-face) + (:match ,elixir-ts--definition-keywords-re @target-identifier)) + (call target: (identifier) @target-identifier + (arguments + (call target: (identifier) @font-lock-function-name-face)) + (:match ,elixir-ts--definition-keywords-re @target-identifier)) + (call target: (identifier) @target-identifier + (arguments + (binary_operator + left: (call target: (identifier) @font-lock-function-name-face))) + (:match ,elixir-ts--definition-keywords-re @target-identifier)) + (call target: (identifier) @target-identifier + (arguments (identifier) @font-lock-function-name-face) + (do_block) + (:match ,elixir-ts--definition-keywords-re @target-identifier)) + (call target: (identifier) @target-identifier + (arguments + (call target: (identifier) @font-lock-function-name-face)) + (do_block) + (:match ,elixir-ts--definition-keywords-re @target-identifier)) + (call target: (identifier) @target-identifier + (arguments + (binary_operator + left: (call target: (identifier) @font-lock-function-name-face))) + (do_block) + (:match ,elixir-ts--definition-keywords-re @target-identifier)) + (unary_operator + operator: "@" + (call (arguments + (binary_operator + left: (call target: (identifier) @font-lock-function-name-face)))))) + + ;; A function definition like "def _foo" is valid, but we should + ;; not apply the comment-face unless its a non-function identifier, so + ;; the comment matches has to be after the function matches. :language 'elixir - :feature 'elixir-string-interpolation - :override t - '((string - [ - quoted_end: _ @font-lock-string-face - quoted_start: _ @font-lock-string-face - (quoted_content) @font-lock-string-face - (interpolation - "#{" @font-lock-regexp-grouping-backslash "}" - @font-lock-regexp-grouping-backslash) - ]) - (charlist - [ - quoted_end: _ @font-lock-string-face - quoted_start: _ @font-lock-string-face - (quoted_content) @font-lock-string-face - (interpolation - "#{" @font-lock-regexp-grouping-backslash "}" - @font-lock-regexp-grouping-backslash) - ])) + :feature 'elixir-comment + '((comment) @font-lock-comment-face + ((identifier) @font-lock-comment-face + (:match "^_[a-z]\\|^_$" @font-lock-comment-face))) :language 'elixir - :feature 'elixir-keyword - `(,elixir-ts--reserved-keywords-vector - @font-lock-keyword-face - (binary_operator - operator: _ @font-lock-keyword-face - (:match ,elixir-ts--reserved-keywords-re @font-lock-keyword-face))) + :feature 'elixir-variable + `((call target: (identifier) + (arguments + (binary_operator + (call target: (identifier) + (arguments ((identifier) @font-lock-variable-use-face)))))) + (call target: (identifier) + (arguments + (call target: (identifier) + (arguments ((identifier)) @font-lock-variable-use-face)))) + (dot left: (identifier) @font-lock-variable-use-face operator: "." )) :language 'elixir :feature 'elixir-doc - :override t `((unary_operator - operator: "@" @elixir-ts-font-comment-doc-attribute-face + operator: "@" @elixir-ts-comment-doc-attribute operand: (call - target: (identifier) @elixir-ts-font-comment-doc-identifier-face + target: (identifier) @elixir-ts-comment-doc-identifier ;; Arguments can be optional, so adding another ;; entry without arguments. ;; If we don't handle then we don't apply font @@ -395,109 +433,128 @@ elixir-ts--font-lock-settings (charlist) @font-lock-doc-face (sigil) @font-lock-doc-face (boolean) @font-lock-doc-face + (keywords) @font-lock-doc-face ])) (:match ,elixir-ts--doc-keywords-re - @elixir-ts-font-comment-doc-identifier-face)) + @elixir-ts-comment-doc-identifier)) (unary_operator - operator: "@" @elixir-ts-font-comment-doc-attribute-face + operator: "@" @elixir-ts-comment-doc-attribute operand: (call - target: (identifier) @elixir-ts-font-comment-doc-identifier-face) + target: (identifier) @elixir-ts-comment-doc-identifier) (:match ,elixir-ts--doc-keywords-re - @elixir-ts-font-comment-doc-identifier-face))) + @elixir-ts-comment-doc-identifier))) :language 'elixir - :feature 'elixir-unary-operator - `((unary_operator operator: "@" @font-lock-preprocessor-face - operand: [ - (identifier) @font-lock-preprocessor-face - (call target: (identifier) - @font-lock-preprocessor-face) - (boolean) @font-lock-preprocessor-face - (nil) @font-lock-preprocessor-face - ]) + :feature 'elixir-string + '((interpolation + "#{" @font-lock-escape-face + "}" @font-lock-escape-face) + (string (quoted_content) @font-lock-string-face) + (quoted_keyword (quoted_content) @font-lock-string-face) + (charlist (quoted_content) @font-lock-string-face) + ["\"" "'" "\"\"\""] @font-lock-string-face) - (unary_operator operator: "&") @font-lock-function-name-face - (operator_identifier) @font-lock-operator-face) + :language 'elixir + :feature 'elixir-sigil + `((sigil + (sigil_name) @elixir-ts-sigil-name + (quoted_content) @font-lock-string-face + ;; HEEx and Surface templates will handled by + ;; heex-ts-mode if its available. + (:match "^[^HF]$" @elixir-ts-sigil-name)) + @font-lock-string-face + (sigil + (sigil_name) @font-lock-regexp-face + (:match "^[rR]$" @font-lock-regexp-face)) + @font-lock-regexp-face + (sigil + "~" @font-lock-string-face + (sigil_name) @font-lock-string-face + quoted_start: _ @font-lock-string-face + quoted_end: _ @font-lock-string-face)) :language 'elixir :feature 'elixir-operator - '((binary_operator operator: _ @font-lock-operator-face) - (dot operator: _ @font-lock-operator-face) - (stab_clause operator: _ @font-lock-operator-face) - - [(boolean) (nil)] @font-lock-constant-face - [(integer) (float)] @font-lock-number-face - (alias) @font-lock-type-face - (call target: (dot left: (atom) @font-lock-type-face)) - (char) @font-lock-constant-face - [(atom) (quoted_atom)] @font-lock-type-face - [(keyword) (quoted_keyword)] @font-lock-builtin-face) + `(["!"] @font-lock-negation-char-face + ["%"] @font-lock-bracket-face + ["," ";"] @font-lock-operator-face + ["(" ")" "[" "]" "{" "}" "<<" ">>"] @font-lock-bracket-face) :language 'elixir - :feature 'elixir-call - `((call - target: (identifier) @font-lock-keyword-face - (:match ,elixir-ts--definition-keywords-re @font-lock-keyword-face)) - (call - target: (identifier) @font-lock-keyword-face - (:match ,elixir-ts--kernel-keywords-re @font-lock-keyword-face)) - (call - target: [(identifier) @font-lock-function-name-face - (dot right: (identifier) @font-lock-keyword-face)]) + :feature 'elixir-data-type + '([(atom) (alias)] @font-lock-type-face + (keywords (pair key: (keyword) @elixir-ts-keyword-key)) + [(keyword) (quoted_keyword)] @elixir-ts-atom + [(boolean) (nil)] @elixir-ts-atom + (unary_operator operator: "@" @elixir-ts-attribute + operand: [ + (identifier) @elixir-ts-attribute + (call target: (identifier) + @elixir-ts-attribute) + (boolean) @elixir-ts-attribute + (nil) @elixir-ts-attribute + ]) + (operator_identifier) @font-lock-operator-face) + + :language 'elixir + :feature 'elixir-keyword + `(,elixir-ts--reserved-keywords-vector + @font-lock-keyword-face + (binary_operator + operator: _ @font-lock-keyword-face + (:match ,elixir-ts--reserved-keywords-re @font-lock-keyword-face)) + (binary_operator operator: _ @font-lock-operator-face) (call target: (identifier) @font-lock-keyword-face - (arguments - [ - (identifier) @font-lock-keyword-face - (binary_operator - left: (identifier) @font-lock-keyword-face - operator: "when") - ]) (:match ,elixir-ts--definition-keywords-re @font-lock-keyword-face)) (call target: (identifier) @font-lock-keyword-face - (arguments - (binary_operator - operator: "|>" - right: (identifier))) - (:match ,elixir-ts--definition-keywords-re @font-lock-keyword-face))) + (:match ,elixir-ts--kernel-keywords-re @font-lock-keyword-face))) :language 'elixir - :feature 'elixir-constant - `((binary_operator operator: "|>" right: (identifier) - @font-lock-function-name-face) - ((identifier) @font-lock-keyword-face - (:match ,elixir-ts--builtin-keywords-re - @font-lock-keyword-face)) - ((identifier) @font-lock-comment-face - (:match "^_" @font-lock-comment-face)) - (identifier) @font-lock-function-name-face - ["%"] @font-lock-keyward-face - ["," ";"] @font-lock-keyword-face - ["(" ")" "[" "]" "{" "}" "<<" ">>"] @font-lock-keyword-face) + :feature 'elixir-function-call + '((call target: (identifier) @font-lock-function-call-face) + (unary_operator operator: "&" @font-lock-operator-face + operand: (binary_operator + left: (identifier) + @font-lock-function-call-face + operator: "/" right: (integer))) + (call + target: (dot right: (identifier) @font-lock-function-call-face)) + (unary_operator operator: "&" @font-lock-variable-name-face + operand: (integer) @font-lock-variable-name-face) + (unary_operator operator: "&" @font-lock-operator-face + operand: (list))) :language 'elixir - :feature 'elixir-sigil + :feature 'elixir-string-escape :override t - `((sigil - (sigil_name) @elixir-ts-font-sigil-name-face - (:match "^[^HF]$" @elixir-ts-font-sigil-name-face)) - @font-lock-string-face - (sigil - (sigil_name) @font-lock-regexp-face - (:match "^[rR]$" @font-lock-regexp-face)) - @font-lock-regexp-face - (sigil - "~" @font-lock-string-face - (sigil_name) @elixir-ts-font-sigil-name-face - quoted_start: _ @font-lock-string-face - quoted_end: _ @font-lock-string-face - (:match "^[HF]$" @elixir-ts-font-sigil-name-face))) + `((escape_sequence) @font-lock-escape-face) :language 'elixir - :feature 'elixir-string-escape + :feature 'elixir-number + '([(integer) (float)] @font-lock-number-face) + + :language 'elixir + :feature 'elixir-variable + '((binary_operator left: (identifier) @font-lock-variable-name-face) + (binary_operator right: (identifier) @font-lock-variable-name-face) + (arguments ( (identifier) @font-lock-variable-name-face)) + (tuple (identifier) @font-lock-variable-name-face) + (list (identifier) @font-lock-variable-name-face) + (pair value: (identifier) @font-lock-variable-name-face) + (body (identifier) @font-lock-variable-name-face) + (unary_operator operand: (identifier) @font-lock-variable-name-face) + (interpolation (identifier) @font-lock-variable-name-face) + (do_block (identifier) @font-lock-variable-name-face)) + + :language 'elixir + :feature 'elixir-builtin :override t - `((escape_sequence) @font-lock-regexp-grouping-backslash)) + `(((identifier) @font-lock-builtin-face + (:match ,elixir-ts--builtin-keywords-re + @font-lock-builtin-face)))) + "Tree-sitter font-lock settings.") (defvar elixir-ts--treesit-range-rules @@ -640,10 +697,12 @@ elixir-ts-mode ;; Font-lock. (setq-local treesit-font-lock-settings elixir-ts--font-lock-settings) (setq-local treesit-font-lock-feature-list - '(( elixir-comment elixir-constant elixir-doc ) - ( elixir-string elixir-keyword elixir-unary-operator - elixir-call elixir-operator ) - ( elixir-sigil elixir-string-escape elixir-string-interpolation))) + '(( elixir-comment elixir-doc elixir-function-name) + ( elixir-string elixir-keyword elixir-data-type) + ( elixir-sigil elixir-variable elixir-builtin + elixir-string-escape) + ( elixir-function-call elixir-operator elixir-number ))) + ;; Imenu. (setq-local treesit-simple-imenu-settings @@ -675,13 +734,13 @@ elixir-ts-mode heex-ts--indent-rules)) (setq-local treesit-font-lock-feature-list - '(( elixir-comment elixir-constant elixir-doc + '(( elixir-comment elixir-doc elixir-function-name heex-comment heex-keyword heex-doctype ) - ( elixir-string elixir-keyword elixir-unary-operator - elixir-call elixir-operator - heex-component heex-tag heex-attribute heex-string) - ( elixir-sigil elixir-string-escape - elixir-string-interpolation )))) + ( elixir-string elixir-keyword elixir-data-type + heex-component heex-tag heex-attribute heex-string ) + ( elixir-sigil elixir-variable elixir-builtin + elixir-string-escape) + ( elixir-function-call elixir-operator elixir-number )))) (treesit-major-mode-setup) (setq-local syntax-propertize-function #'elixir-ts--syntax-propertize))) commit 265ffe59fbd7c01e2bd5a8c6dcac9035c00de004 Author: Po Lu Date: Wed Nov 29 10:46:42 2023 +0800 Clean up some redundant or otherwise suspect code * java/org/gnu/emacs/EmacsOpenActivity.java (onCreate): Don't check if URI is non-NULL, for instanceof checks this also. * java/org/gnu/emacs/EmacsSafThread.java (accessDocument1): Don't check !writable twice. * java/org/gnu/emacs/EmacsService.java (documentIdFromName): Designate this function as public, since it is called through JNI. diff --git a/java/org/gnu/emacs/EmacsOpenActivity.java b/java/org/gnu/emacs/EmacsOpenActivity.java index 5cca6cfcdff..32a79d1a797 100644 --- a/java/org/gnu/emacs/EmacsOpenActivity.java +++ b/java/org/gnu/emacs/EmacsOpenActivity.java @@ -533,8 +533,7 @@ private class EmacsClientThread extends Thread else uri = intent.getParcelableExtra (Intent.EXTRA_STREAM); - if (uri != null - && (scheme = uri.getScheme ()) != null + if ((scheme = uri.getScheme ()) != null && scheme.equals ("content")) { tem1 = EmacsService.buildContentName (uri); diff --git a/java/org/gnu/emacs/EmacsSafThread.java b/java/org/gnu/emacs/EmacsSafThread.java index 1b62662b4fc..7917e2d4880 100644 --- a/java/org/gnu/emacs/EmacsSafThread.java +++ b/java/org/gnu/emacs/EmacsSafThread.java @@ -1430,9 +1430,6 @@ type is either NULL (in which case id should also be NULL) or /* If so, don't check for FLAG_SUPPORTS_WRITE. Check for FLAG_DIR_SUPPORTS_CREATE instead. */ - if (!writable) - return 0; - index = cursor.getColumnIndex (Document.COLUMN_FLAGS); if (index < 0) return -3; diff --git a/java/org/gnu/emacs/EmacsService.java b/java/org/gnu/emacs/EmacsService.java index 3cc37dd992d..33832505333 100644 --- a/java/org/gnu/emacs/EmacsService.java +++ b/java/org/gnu/emacs/EmacsService.java @@ -1413,7 +1413,7 @@ else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) of OperationCanceledException, SecurityException, FileNotFoundException, or UnsupportedOperationException. */ - private int + public int documentIdFromName (String tree_uri, String name, String[] id_return) { /* Start the thread used to run SAF requests if it isn't already commit 5a0250f76676d8750f42bbca1af5c4553846949b Author: João Távora Date: Tue Nov 28 18:47:09 2023 -0600 Jsonrpc: prevent while-no-input messing with jsonrpc-request 'jsonrpc-request' already has its "interrupt on user input" mechanism base on 'sit-for'. If called from a situation that uses while-no-input to do basically the same, that mechanism may become confused, so it's important to prevent that interfence. This was confirmed to be a problem when using the Corfu completion front-end. See also https://github.com/joaotavora/eglot/discussions/1127#discussioncomment-7277567 Many thanks to JD Smith for helping me debug this and pointing in the right direction. * lisp/jsonrpc.el (Version): Bump to 1.0.18 (jsonrpc-request): Bind throw-on-input to nil diff --git a/lisp/jsonrpc.el b/lisp/jsonrpc.el index 3cba9636e02..849a8d8eaee 100644 --- a/lisp/jsonrpc.el +++ b/lisp/jsonrpc.el @@ -4,7 +4,7 @@ ;; Author: João Távora ;; Keywords: processes, languages, extensions -;; Version: 1.0.17 +;; Version: 1.0.18 ;; Package-Requires: ((emacs "25.2")) ;; This is a GNU ELPA :core package. Avoid functionality that is not @@ -288,6 +288,7 @@ jsonrpc-request ignored." (let* ((tag (cl-gensym "jsonrpc-request-catch-tag")) id-and-timer canceled + (throw-on-input nil) (retval (unwind-protect (catch tag commit 02d88e36e911e76842369e565ca2dae9a7922f7b Author: João Távora Date: Tue Nov 28 18:33:09 2023 -0600 Unbreak Eglot, Jsonrpc as EIEIO inches closer to CLOS (bug#67480) EIEIO is an innacurate emulation of CLOS in many aspects and one of them in accessor definition. Before this commit commit 6c47931a1ad4de4af3f147b9604169c2441100fe Author: Brandon Date: Sat Nov 4 17:11:32 2023 -0400 Make EIEIO ':accessor' behave like ':reader' when reading (bug#66938) An :initform-less, non-:initarg'ed slot with be read using an :accessor which would just return nil. This is EIEIO specific of course, but it made for (my) sloppy programming in jsonrpc.el and eglot.el. Tightening up the rules a bit meant these things broke and now I'm fixing them. * lisp/jsonrpc.el (jsonrpc-connection): Add a bunch of :initform nil (jsonrpc-process-connection): Add a bunch of :initform nil * lisp/progmodes/eglot.el (eglot-lsp-server): Add a bunch of :initform nil diff --git a/lisp/jsonrpc.el b/lisp/jsonrpc.el index 52ffb220d8b..3cba9636e02 100644 --- a/lisp/jsonrpc.el +++ b/lisp/jsonrpc.el @@ -64,6 +64,7 @@ jsonrpc-connection :initarg :notification-dispatcher :documentation "Dispatcher for remotely invoked notifications.") (last-error + :initform nil :accessor jsonrpc-last-error :documentation "Last JSONRPC error message received from endpoint.") (-request-continuations @@ -71,6 +72,7 @@ jsonrpc-connection :accessor jsonrpc--request-continuations :documentation "A hash table of request ID to continuation lambdas.") (-events-buffer + :initform nil :accessor jsonrpc--events-buffer :documentation "A buffer pretty-printing the JSONRPC events") (-events-buffer-scrollback-size @@ -353,6 +355,7 @@ jsonrpc-process-connection :initarg :process :accessor jsonrpc--process :documentation "Process object wrapped by the this connection.") (-expected-bytes + :initform nil :accessor jsonrpc--expected-bytes :documentation "How many bytes declared by server.") (-on-shutdown diff --git a/lisp/progmodes/eglot.el b/lisp/progmodes/eglot.el index 48ea33c3ee1..d410367f902 100644 --- a/lisp/progmodes/eglot.el +++ b/lisp/progmodes/eglot.el @@ -977,15 +977,19 @@ eglot-lsp-server :accessor eglot--project-nickname :reader eglot-project-nickname) (languages + :initform nil :documentation "Alist ((MODE . LANGUAGE-ID-STRING)...) of managed languages." :accessor eglot--languages) (capabilities + :initform nil :documentation "JSON object containing server capabilities." :accessor eglot--capabilities) (server-info + :initform nil :documentation "JSON object containing server info." :accessor eglot--server-info) (shutdown-requested + :initform nil :documentation "Flag set when server is shutting down." :accessor eglot--shutdown-requested) (project @@ -1002,6 +1006,7 @@ eglot-lsp-server :documentation "Map (DIR -> (WATCH ID1 ID2...)) for `didChangeWatchedFiles'." :initform (make-hash-table :test #'equal) :accessor eglot--file-watches) (managed-buffers + :initform nil :documentation "List of buffers managed by server." :accessor eglot--managed-buffers) (saved-initargs