Merge remote-tracking branch 'origin/master' into feature/android

This commit is contained in:
Po Lu 2023-01-17 22:11:31 +08:00
commit 6253e7e742
42 changed files with 714 additions and 65 deletions

View file

@ -3390,7 +3390,8 @@ first, before handlers for jobs such as remote file access.
@code{file-readable-p}, @code{file-regular-p},
@code{file-remote-p}, @code{file-selinux-context},
@code{file-symlink-p}, @code{file-system-info},
@code{file-truename}, @code{file-writable-p},
@code{file-truename}, @code{file-user-uid},
@code{file-writable-p},
@code{find-backup-file-name},@*
@code{get-file-buffer},
@code{insert-directory},
@ -3451,7 +3452,8 @@ first, before handlers for jobs such as remote file access.
@code{file-readable-p}, @code{file-regular-p},
@code{file-remote-p}, @code{file-selinux-context},
@code{file-symlink-p}, @code{file-system-info},
@code{file-truename}, @code{file-writable-p},
@code{file-truename}, @code{file-user-uid},
@code{file-writable-p},
@code{find-backup-file-name},
@code{get-file-buffer},
@code{insert-directory},

View file

@ -1280,6 +1280,16 @@ This function returns the real @acronym{UID} of the user.
This function returns the effective @acronym{UID} of the user.
@end defun
@defun file-user-uid
This function returns the connection-local value for the user's
effective @acronym{UID}. If @code{default-directory} is local, this
is equivalent to @code{user-uid}, but for remote files (@pxref{Remote
Files, , , emacs, The GNU Emacs Manual}), it will return the
@acronym{UID} for the user associated with that remote connection; if
the remote connection has no associated user, it will instead return
-1.
@end defun
@cindex GID
@defun group-gid
This function returns the effective @acronym{GID} of the Emacs process.

View file

@ -983,6 +983,13 @@ whenever you change the current directory to a different host
the value will automatically update to reflect the search path on that
host.
@vindex $UID
@item $UID
This returns the effective @acronym{UID} for the current user. This
variable is connection-aware, so when the current directory is remote,
its value will be @acronym{UID} for the user associated with that
remote connection.
@vindex $_
@item $_
This refers to the last argument of the last command. With a
@ -1014,6 +1021,7 @@ that are currently visible in the Eshell window. They are both
copied to the environment, so external commands invoked from
Eshell can consult them to do the right thing.
@vindex $INSIDE_EMACS
@item $INSIDE_EMACS
This variable indicates to external commands that they are being
invoked from within Emacs so they can adjust their behavior if

View file

@ -235,6 +235,12 @@ compared reliably at all.
This warning can be suppressed using 'with-suppressed-warnings' with
the warning name 'suspicious'.
+++
** New function 'file-user-uid'.
This function is like 'user-uid', but is aware of file name handlers,
so it will return the remote UID for remote files (or -1 if the
connection has no associated user).
* Changes in Emacs 30.1 on Non-Free Operating Systems

View file

@ -1380,6 +1380,9 @@ See Info node `(elisp) Integer Basics'."
;; (apply F ... (list X Y ...)) -> (funcall F ... X Y ...)
((eq (car-safe last) 'list)
`(funcall ,fn ,@(butlast (cddr form)) ,@(cdr last)))
;; (apply F ... (cons X Y)) -> (apply F ... X Y)
((eq (car-safe last) 'cons)
(append (butlast form) (cdr last)))
(t form)))
form)))

View file

@ -1575,7 +1575,7 @@ extra args."
"`%s' called with %d args to fill %d format field(s)" (car form)
nargs nfields)))))
(dolist (elt '(format message error))
(dolist (elt '(format message format-message error))
(put elt 'byte-compile-format-like t))
(defun byte-compile--suspicious-defcustom-choice (type)

View file

@ -52,7 +52,7 @@ as is common with most shells."
(defcustom eshell-prompt-function
(lambda ()
(concat (abbreviate-file-name (eshell/pwd))
(if (= (user-uid) 0) " # " " $ ")))
(if (= (file-user-uid) 0) " # " " $ ")))
"A function that returns the Eshell prompt string.
Make sure to update `eshell-prompt-regexp' so that it will match your
prompt."

View file

@ -162,6 +162,7 @@ if they are quoted with a backslash."
("COLUMNS" ,(lambda () (window-body-width nil 'remap)) t t)
("LINES" ,(lambda () (window-body-height nil 'remap)) t t)
("INSIDE_EMACS" eshell-inside-emacs t)
("UID" ,(lambda () (file-user-uid)) nil t)
;; for esh-ext.el
("PATH" (,(lambda () (string-join (eshell-get-path t) (path-separator)))

View file

@ -373,13 +373,13 @@ otherwise."
:type '(string))
(defcustom hfy-exclude-file-rules
'("\\.flc$"
"/CVS/.*"
".*~$"
"/\\.git\\(?:/.*\\)?$")
"Define some regular expressions to exclude files"
'("\\.flc\\'"
"/CVS/"
"~\\'"
"/\\.git\\(?:/\\|\\'\\)")
"Regular expressions matching files to exclude."
:tag "exclude-rules"
:type '(list string)
:type '(repeat regexp)
:version "29.1")
(defcustom hfy-display-class nil
@ -1835,7 +1835,7 @@ Strips any leading \"./\" from each filename."
(seq-some (lambda (r)
(string-match r f))
hfy-exclude-file-rules)))
(directory-files-recursively "." ".*" nil t)))
(directory-files-recursively "." "" nil t)))
;; strip the filename off, return a directory name
;; not a particularly thorough implementation, but it will be

View file

@ -153,6 +153,7 @@ It is used for TCP/IP devices."
(file-symlink-p . tramp-handle-file-symlink-p)
(file-system-info . tramp-adb-handle-file-system-info)
(file-truename . tramp-handle-file-truename)
(file-user-uid . tramp-handle-file-user-uid)
(file-writable-p . tramp-adb-handle-file-writable-p)
(find-backup-file-name . tramp-handle-find-backup-file-name)
;; `get-file-buffer' performed by default handler.

View file

@ -265,6 +265,7 @@ It must be supported by libarchive(3).")
(file-symlink-p . tramp-handle-file-symlink-p)
(file-system-info . tramp-archive-handle-file-system-info)
(file-truename . tramp-archive-handle-file-truename)
(file-user-uid . tramp-archive-handle-file-user-uid)
(file-writable-p . ignore)
(find-backup-file-name . ignore)
;; `get-file-buffer' performed by default handler.
@ -701,6 +702,12 @@ offered."
(let ((default-directory (file-name-directory archive)))
(temporary-file-directory))))
(defun tramp-archive-handle-file-user-uid ()
"Like `user-uid' for file archives."
(with-parsed-tramp-archive-file-name default-directory nil
(let ((default-directory (file-name-directory archive)))
(file-user-uid))))
(defun tramp-archive-handle-not-implemented (operation &rest args)
"Generic handler for operations not implemented for file archives."
(let ((v (ignore-errors

View file

@ -204,6 +204,7 @@ If NAME doesn't belong to an encrypted remote directory, return nil."
(file-symlink-p . tramp-handle-file-symlink-p)
(file-system-info . tramp-crypt-handle-file-system-info)
;; `file-truename' performed by default handler.
(file-user-uid . tramp-handle-file-user-uid)
(file-writable-p . tramp-crypt-handle-file-writable-p)
(find-backup-file-name . tramp-handle-find-backup-file-name)
;; `get-file-buffer' performed by default handler.

View file

@ -798,6 +798,7 @@ It has been changed in GVFS 1.14.")
(file-symlink-p . tramp-handle-file-symlink-p)
(file-system-info . tramp-gvfs-handle-file-system-info)
(file-truename . tramp-handle-file-truename)
(file-user-uid . tramp-handle-file-user-uid)
(file-writable-p . tramp-handle-file-writable-p)
(find-backup-file-name . tramp-handle-find-backup-file-name)
;; `get-file-buffer' performed by default handler.

View file

@ -118,6 +118,7 @@
(file-symlink-p . tramp-handle-file-symlink-p)
(file-system-info . tramp-rclone-handle-file-system-info)
(file-truename . tramp-handle-file-truename)
(file-user-uid . tramp-handle-file-user-uid)
(file-writable-p . tramp-handle-file-writable-p)
(find-backup-file-name . tramp-handle-find-backup-file-name)
;; `get-file-buffer' performed by default handler.

View file

@ -1086,6 +1086,7 @@ Format specifiers \"%s\" are replaced before the script is used.")
(file-symlink-p . tramp-handle-file-symlink-p)
(file-system-info . tramp-sh-handle-file-system-info)
(file-truename . tramp-sh-handle-file-truename)
(file-user-uid . tramp-handle-file-user-uid)
(file-writable-p . tramp-sh-handle-file-writable-p)
(find-backup-file-name . tramp-handle-find-backup-file-name)
;; `get-file-buffer' performed by default handler.

View file

@ -269,6 +269,7 @@ See `tramp-actions-before-shell' for more info.")
(file-symlink-p . tramp-handle-file-symlink-p)
(file-system-info . tramp-smb-handle-file-system-info)
(file-truename . tramp-handle-file-truename)
(file-user-uid . tramp-handle-file-user-uid)
(file-writable-p . tramp-smb-handle-file-writable-p)
(find-backup-file-name . tramp-handle-find-backup-file-name)
;; `get-file-buffer' performed by default handler.

View file

@ -124,6 +124,7 @@
(file-symlink-p . tramp-handle-file-symlink-p)
(file-system-info . tramp-sshfs-handle-file-system-info)
(file-truename . tramp-handle-file-truename)
(file-user-uid . tramp-handle-file-user-uid)
(file-writable-p . tramp-sshfs-handle-file-writable-p)
(find-backup-file-name . tramp-handle-find-backup-file-name)
;; `get-file-buffer' performed by default handler.

View file

@ -114,6 +114,7 @@ See `tramp-actions-before-shell' for more info.")
(file-symlink-p . tramp-handle-file-symlink-p)
(file-system-info . tramp-sudoedit-handle-file-system-info)
(file-truename . tramp-sudoedit-handle-file-truename)
(file-user-uid . tramp-handle-file-user-uid)
(file-writable-p . tramp-sudoedit-handle-file-writable-p)
(find-backup-file-name . tramp-handle-find-backup-file-name)
;; `get-file-buffer' performed by default handler.

View file

@ -2632,7 +2632,9 @@ Must be handled by the callers."
'(exec-path make-nearby-temp-file make-process process-file
shell-command start-file-process temporary-file-directory
;; Emacs 29+ only.
list-system-processes memory-info process-attributes))
list-system-processes memory-info process-attributes
;; Emacs 30+ only.
file-user-uid))
default-directory)
;; PROC.
((member operation '(file-notify-rm-watch file-notify-valid-p))
@ -3714,6 +3716,15 @@ Let-bind it when necessary.")
vec (concat "~" (substring filename (match-beginning 1))))
(tramp-make-tramp-file-name (tramp-dissect-file-name filename)))))
(defun tramp-handle-file-user-uid ()
"Like `user-uid' for Tramp files."
(let ((v (tramp-dissect-file-name default-directory)))
(or (tramp-get-remote-uid v 'integer)
;; Some handlers for `tramp-get-remote-uid' return nil if they
;; can't get the UID; always return -1 in this case for
;; consistency.
-1)))
(defun tramp-handle-access-file (filename string)
"Like `access-file' for Tramp files."
(setq filename (file-truename filename))

View file

@ -10863,7 +10863,13 @@ This function might do hidden buffer changes."
;; types; other identifiers could just as well be
;; constants in C++.
(memq at-type '(known found)))))
(throw 'at-decl-or-cast t)
(progn
;; The user may be part way through typing a statement
;; beginning with an identifier. This makes a 'maybe
;; type in the following "declarator"'s arglist suspect.
(when (eq at-type 'maybe)
(setq unsafe-maybe t))
(throw 'at-decl-or-cast t))
;; CASE 7
;; Can't be a valid declaration or cast, but if we've found a
;; specifier it can't be anything else either, so treat it as

View file

@ -161,6 +161,10 @@ the subtrees."
(setq-local treesit-simple-indent-rules
dockerfile-ts-mode--indent-rules)
;; Navigation
(setq-local treesit-sentence-type-regexp
"instruction")
;; Font-lock.
(setq-local treesit-font-lock-settings
dockerfile-ts-mode--font-lock-settings)

View file

@ -1075,7 +1075,7 @@ suitable root directory for a given LSP server's purposes."
;;;###autoload
(defun eglot (managed-major-mode project class contact language-id
&optional interactive)
&optional _interactive)
"Start LSP server in support of PROJECT's buffers under MANAGED-MAJOR-MODE.
This starts a Language Server Protocol (LSP) server suitable for the
@ -1112,17 +1112,17 @@ described in `eglot-server-programs', which see.
LANGUAGE-ID is the language ID string to send to the server for
MANAGED-MAJOR-MODE, which matters to a minority of servers.
INTERACTIVE is t if called interactively."
(interactive (append (eglot--guess-contact t) '(t)))
(setq managed-major-mode (eglot--ensure-list managed-major-mode))
(let* ((current-server (eglot-current-server))
(live-p (and current-server (jsonrpc-running-p current-server))))
(if (and live-p
interactive
(y-or-n-p "[eglot] Live process found, reconnect instead? "))
(eglot-reconnect current-server interactive)
(when live-p (ignore-errors (eglot-shutdown current-server)))
(eglot--connect managed-major-mode project class contact language-id))))
INTERACTIVE is ignored and provided for backward compatibility."
(interactive
(let ((current-server (eglot-current-server)))
(unless (or (null current-server)
(y-or-n-p "\
[eglot] Shut down current connection before attempting new one?"))
(user-error "[eglot] Connection attempt aborted by user."))
(prog1 (append (eglot--guess-contact t) '(t))
(when current-server (ignore-errors (eglot-shutdown current-server))))))
(eglot--connect (eglot--ensure-list managed-major-mode)
project class contact language-id))
(defun eglot-reconnect (server &optional interactive)
"Reconnect to SERVER.

View file

@ -3454,13 +3454,16 @@ This function is intended for use in `after-change-functions'."
((parent-is "statement_block") parent-bol js-indent-level)
;; JSX
((node-is "jsx_fragment") parent typescript-ts-mode-indent-offset)
((node-is "jsx_element") parent typescript-ts-mode-indent-offset)
((node-is "jsx_expression") parent typescript-ts-mode-indent-offset)
((node-is "jsx_self_closing_element") parent typescript-ts-mode-indent-offset)
((match "<" "jsx_fragment") parent 0)
((parent-is "jsx_fragment") parent js-indent-level)
((node-is "jsx_closing_element") parent 0)
((node-is "/") parent 0)
((node-is ">") parent 0)))))
((node-is "jsx_element") parent js-indent-level)
((parent-is "jsx_element") parent js-indent-level)
((parent-is "jsx_opening_element") parent js-indent-level)
((parent-is "jsx_expression") parent-bol js-indent-level)
((match "/" "jsx_self_closing_element") parent 0)
((parent-is "jsx_self_closing_element") parent js-indent-level)
(no-node parent-bol 0)))))
(defvar js--treesit-keywords
'("as" "async" "await" "break" "case" "catch" "class" "const" "continue"

View file

@ -147,6 +147,8 @@ Return nil if there is no name or if NODE is not a defun node."
(rx (or "pair" "object")))
(setq-local treesit-defun-name-function #'json-ts-mode--defun-name)
(setq-local treesit-sentence-type-regexp "pair")
;; Font-lock.
(setq-local treesit-font-lock-settings json-ts-mode--font-lock-settings)
(setq-local treesit-font-lock-feature-list

View file

@ -780,12 +780,20 @@ i.e. expr of def foo(args) = expr is returned."
;; but with node set to the statement and parent set to
;; body_statement for all others. ... Fine. Be that way.
;; Ditto for "block" and "block_body"
((node-is "body_statement") parent-bol ruby-indent-level)
((parent-is "body_statement") (ruby-ts--bol ruby-ts--grand-parent-node) ruby-indent-level)
((match "end" "do_block") parent-bol 0)
((n-p-gp "block_body" "block" nil) parent-bol ruby-indent-level)
((n-p-gp nil "block_body" "block") (ruby-ts--bol ruby-ts--grand-parent-node) ruby-indent-level)
((match "}" "block") parent-bol 0)
((node-is "body_statement")
(ruby-ts--block-indent-anchor ruby-ts--parent-node)
ruby-indent-level)
((parent-is "body_statement")
(ruby-ts--block-indent-anchor ruby-ts--grand-parent-node)
ruby-indent-level)
((match "end" "do_block") (ruby-ts--block-indent-anchor ruby-ts--parent-node) 0)
((n-p-gp "block_body" "block" nil)
(ruby-ts--block-indent-anchor ruby-ts--parent-node)
ruby-indent-level)
((n-p-gp nil "block_body" "block")
(ruby-ts--block-indent-anchor ruby-ts--grand-parent-node)
ruby-indent-level)
((match "}" "block") (ruby-ts--block-indent-anchor ruby-ts--parent-node) 0)
;; Chained strings
((match "string" "chained_string") first-sibling 0)
@ -794,6 +802,18 @@ i.e. expr of def foo(args) = expr is returned."
(catch-all parent-bol ruby-indent-level))))
`((ruby . ,common))))
(defun ruby-ts--block-indent-anchor (block-node-getter)
(lambda (node parent _bol &rest _rest)
(let ((block-node (funcall block-node-getter node parent)))
(save-excursion
(goto-char
(treesit-node-start
(if ruby-block-indent
(ruby-ts--statement-ancestor block-node)
block-node)))
(back-to-indentation)
(point)))))
(defun ruby-ts--class-or-module-p (node)
"Predicate if NODE is a class or module."
(string-match-p ruby-ts--class-or-module-regex (treesit-node-type node)))

View file

@ -97,13 +97,15 @@ Argument LANGUAGE is either `typescript' or `tsx'."
((parent-is "binary_expression") parent-bol typescript-ts-mode-indent-offset)
,@(when (eq language 'tsx)
`(((node-is "jsx_fragment") parent typescript-ts-mode-indent-offset)
((node-is "jsx_element") parent typescript-ts-mode-indent-offset)
((node-is "jsx_expression") parent typescript-ts-mode-indent-offset)
((node-is "jsx_self_closing_element") parent typescript-ts-mode-indent-offset)
`(((match "<" "jsx_fragment") parent 0)
((parent-is "jsx_fragment") parent typescript-ts-mode-indent-offset)
((node-is "jsx_closing_element") parent 0)
((node-is "/") parent 0)
((node-is ">") parent 0)))
((node-is "jsx_element") parent typescript-ts-mode-indent-offset)
((parent-is "jsx_element") parent typescript-ts-mode-indent-offset)
((parent-is "jsx_opening_element") parent typescript-ts-mode-indent-offset)
((parent-is "jsx_expression") parent-bol typescript-ts-mode-indent-offset)
((match "/" "jsx_self_closing_element") parent 0)
((parent-is "jsx_self_closing_element") parent typescript-ts-mode-indent-offset)))
(no-node parent-bol 0))))
(defvar typescript-ts-mode--keywords

View file

@ -4730,6 +4730,18 @@ Also see the `async-shell-command-buffer' variable."
action))
(user-error "Shell command in progress"))))
(defun file-user-uid ()
"Return the connection-local effective uid.
This is similar to `user-uid', but may invoke a file name handler
based on `default-directory'. See Info node `(elisp)Magic File
Names'.
If a file name handler is unable to retrieve the effective uid,
this function will instead return -1."
(if-let ((handler (find-file-name-handler default-directory 'file-user-uid)))
(funcall handler 'file-user-uid)
(user-uid)))
(defun max-mini-window-lines (&optional frame)
"Compute maximum number of lines for echo area in FRAME.
As defined by `max-mini-window-height'. FRAME defaults to the

View file

@ -2562,12 +2562,14 @@ The variable list SPEC is the same as in `if-let'."
Evaluate each binding in turn, stopping if a binding value is nil.
If all bindings are non-nil, eval BODY and repeat.
The variable list SPEC is the same as in `if-let'."
The variable list SPEC is the same as in `if-let*'."
(declare (indent 1) (debug if-let))
(let ((done (gensym "done")))
`(catch ',done
(while t
(if-let ,spec
;; This is `if-let*', not `if-let', deliberately, despite the
;; name of this macro. See bug#60758.
(if-let* ,spec
(progn
,@body)
(throw ',done nil))))))

View file

@ -1152,7 +1152,6 @@ See `treesit-simple-indent-presets'.")
(and (>= (point) comment-start-bol)
adaptive-fill-regexp
(looking-at adaptive-fill-regexp)
(> (match-end 0) (match-beginning 0))
(match-end 0))))))
;; TODO: Document.
(cons 'grand-parent

View file

@ -65,7 +65,7 @@
:link '(custom-manual "(use-package) Top")
:version "29.1")
(defconst use-package-version "2.4.4"
(defconst use-package-version "2.4.5"
"This version of `use-package'.")
(defcustom use-package-keywords

View file

@ -5,7 +5,7 @@
;; Author: John Wiegley <johnw@newartisans.com>
;; Maintainer: John Wiegley <johnw@newartisans.com>
;; Created: 17 Jun 2012
;; Version: 2.4.4
;; Version: 2.4.5
;; Package-Requires: ((emacs "24.3") (bind-key "2.4"))
;; Keywords: dotemacs startup speed config package extensions
;; URL: https://github.com/jwiegley/use-package

View file

@ -10396,8 +10396,8 @@ to be converted to forward slashes by the caller. */)
#endif /* WINDOWSNT */
/* Query a value from the Windows Registry (under HKCU and HKLM),
where `key` is the registry key, `name` is the name, and `lpdwtype`
is a pointer to the return value's type. `lpwdtype` can be NULL if
where `key' is the registry key, `name' is the name, and `lpdwtype'
is a pointer to the return value's type. `lpwdtype' can be NULL if
you do not care about the type.
Returns: pointer to the value, or null pointer if the key/name does
@ -10664,7 +10664,7 @@ pops up the Windows Run dialog, <lwindow>-<Pause> pops up the "System
Properties" dialog, etc. On Windows 10, no \"Windows\" key
combinations are normally handed to applications. To enable Emacs to
process \"Windows\" key combinations, use the function
`w32-register-hot-key`.
`w32-register-hot-key'.
For Windows 98/ME, see the doc string of `w32-phantom-key-code'. */);
Vw32_pass_lwindow_to_system = Qt;
@ -10683,7 +10683,7 @@ pops up the Windows Run dialog, <rwindow>-<Pause> pops up the "System
Properties" dialog, etc. On Windows 10, no \"Windows\" key
combinations are normally handed to applications. To enable Emacs to
process \"Windows\" key combinations, use the function
`w32-register-hot-key`.
`w32-register-hot-key'.
For Windows 98/ME, see the doc string of `w32-phantom-key-code'. */);
Vw32_pass_rwindow_to_system = Qt;
@ -10698,7 +10698,7 @@ acting on \"Windows\" key events when `w32-pass-lwindow-to-system' or
`w32-pass-rwindow-to-system' is nil.
This variable is only used on Windows 98 and ME. For other Windows
versions, see the documentation of the `w32-register-hot-key`
versions, see the documentation of the `w32-register-hot-key'
function. */);
/* Although 255 is technically not a valid key code, it works and
means that this hack won't interfere with any real key code. */
@ -10732,7 +10732,7 @@ The value can be hyper, super, meta, alt, control or shift for the
respective modifier, or nil to appear as the `lwindow' key.
Any other value will cause the key to be ignored.
Also see the documentation of the `w32-register-hot-key` function. */);
Also see the documentation of the `w32-register-hot-key' function. */);
Vw32_lwindow_modifier = Qnil;
DEFVAR_LISP ("w32-rwindow-modifier",
@ -10742,7 +10742,7 @@ The value can be hyper, super, meta, alt, control or shift for the
respective modifier, or nil to appear as the `rwindow' key.
Any other value will cause the key to be ignored.
Also see the documentation of the `w32-register-hot-key` function. */);
Also see the documentation of the `w32-register-hot-key' function. */);
Vw32_rwindow_modifier = Qnil;
DEFVAR_LISP ("w32-apps-modifier",
@ -11271,7 +11271,7 @@ globals_of_w32fns (void)
get_proc_addr (hm_kernel32, "SetThreadDescription");
/* Support OS dark mode on Windows 10 version 1809 and higher.
See `w32_applytheme` which uses appropriate APIs per version of Windows.
See `w32_applytheme' which uses appropriate APIs per version of Windows.
For future wretches who may need to understand Windows build numbers:
https://docs.microsoft.com/en-us/windows/release-health/release-information
*/

View file

@ -5750,7 +5750,8 @@ xi_device_from_id (struct x_display_info *dpyinfo, int deviceid)
static void
xi_link_touch_point (struct xi_device_t *device,
int detail, double x, double y)
int detail, double x, double y,
struct frame *frame)
{
struct xi_touch_point_t *touchpoint;
@ -5759,6 +5760,7 @@ xi_link_touch_point (struct xi_device_t *device,
touchpoint->x = x;
touchpoint->y = y;
touchpoint->number = detail;
touchpoint->frame = frame;
device->touchpoints = touchpoint;
}
@ -5787,6 +5789,36 @@ xi_unlink_touch_point (int detail,
return false;
}
/* Unlink all touch points associated with the frame F.
This is done upon unmapping or destroying F's window, because
touch point delivery after that point is undefined. */
static void
xi_unlink_touch_points (struct frame *f)
{
struct xi_device_t *device;
struct xi_touch_point_t **next, *last;
int i;
for (i = 0; i < FRAME_DISPLAY_INFO (f)->num_devices; ++i)
{
device = &FRAME_DISPLAY_INFO (f)->devices[i];
/* Now unlink all touch points on DEVICE matching F. */
for (next = &device->touchpoints; (last = *next);)
{
if (last->frame == f)
{
*next = last->next;
xfree (last);
}
else
next = &last->next;
}
}
}
static struct xi_touch_point_t *
xi_find_touch_point (struct xi_device_t *device, int detail)
{
@ -13535,6 +13567,10 @@ xi_disable_devices (struct x_display_info *dpyinfo,
#ifdef HAVE_XINPUT2_2
struct xi_touch_point_t *tem, *last;
#endif
#if defined HAVE_XINPUT2_2 && !defined HAVE_EXT_TOOL_BAR
struct x_output *output;
Lisp_Object tail, frame;
#endif
/* Don't pointlessly copy dpyinfo->devices if there are no devices
to disable. */
@ -13577,6 +13613,34 @@ xi_disable_devices (struct x_display_info *dpyinfo,
tem = tem->next;
xfree (last);
}
#ifndef HAVE_EXT_TOOL_BAR
/* Now look through each frame on DPYINFO. If it has an
outstanding tool bar press for this device, release
the tool bar. */
FOR_EACH_FRAME (tail, frame)
{
if (!FRAME_X_P (XFRAME (frame))
|| (FRAME_DISPLAY_INFO (XFRAME (frame))
!= dpyinfo))
continue;
output = FRAME_OUTPUT_DATA (XFRAME (frame));
if (output->tool_bar_touch_device
== dpyinfo->devices[i].device_id)
{
if (XFRAME (frame)->last_tool_bar_item != -1
&& WINDOWP (XFRAME (frame)->tool_bar_window))
handle_tool_bar_click (XFRAME (frame), 0, 0,
false, 0);
output->tool_bar_touch_device = 0;
}
}
#endif
#endif
goto out;
@ -24209,6 +24273,73 @@ handle_one_xevent (struct x_display_info *dpyinfo,
}
#endif
#ifndef HAVE_EXT_TOOL_BAR
/* Is this a touch from a direct touch device that is in
the tool-bar? */
if (device->direct_p
&& WINDOWP (f->tool_bar_window)
&& WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)))
{
Lisp_Object window;
int x = xev->event_x;
int y = xev->event_y;
window = window_from_coordinates (f, x, y, 0, true, true);
/* Ignore button release events if the mouse
wasn't previously pressed on the tool bar.
We do this because otherwise selecting some
text with the mouse and then releasing it on
the tool bar doesn't stop selecting text,
since the tool bar eats the button up
event. */
tool_bar_p = EQ (window, f->tool_bar_window);
/* If this touch has started in the tool bar, do not
send it to Lisp. Instead, simulate a tool bar
click, releasing it once it goes away. */
if (tool_bar_p)
{
/* Call note_mouse_highlight on the tool bar
item. Otherwise, get_tool_bar_item will
return 1.
This is not necessary when mouse-highlight is
nil. */
if (!NILP (Vmouse_highlight))
{
note_mouse_highlight (f, x, y);
/* Always allow future mouse motion to
update the mouse highlight, no matter
where it is. */
memset (&dpyinfo->last_mouse_glyph, 0,
sizeof dpyinfo->last_mouse_glyph);
dpyinfo->last_mouse_glyph_frame = f;
}
handle_tool_bar_click_with_device (f, x, y, true, 0,
(source
? source->name : Qt));
/* Flush any changes made by that to the front
buffer. */
x_flush_dirty_back_buffer_on (f);
/* Record the device and the touch ID on the
frame. That way, Emacs knows when to dismiss
the tool bar click later. */
FRAME_OUTPUT_DATA (f)->tool_bar_touch_device
= device->device_id;
FRAME_OUTPUT_DATA (f)->tool_bar_touch_id = xev->detail;
goto XI_OTHER;
}
}
#endif
if (!menu_bar_p && !tool_bar_p)
{
if (f && device->direct_p)
@ -24218,13 +24349,16 @@ handle_one_xevent (struct x_display_info *dpyinfo,
x_catch_errors (dpyinfo->display);
if (x_input_grab_touch_events)
XIAllowTouchEvents (dpyinfo->display, xev->deviceid,
xev->detail, xev->event, XIAcceptTouch);
XIAllowTouchEvents (dpyinfo->display,
xev->deviceid,
xev->detail, xev->event,
XIAcceptTouch);
if (!x_had_errors_p (dpyinfo->display))
{
xi_link_touch_point (device, xev->detail, xev->event_x,
xev->event_y);
xi_link_touch_point (device, xev->detail,
xev->event_x,
xev->event_y, f);
inev.ie.kind = TOUCHSCREEN_BEGIN_EVENT;
inev.ie.timestamp = xev->time;
@ -24299,10 +24433,11 @@ handle_one_xevent (struct x_display_info *dpyinfo,
for (touchpoint = device->touchpoints;
touchpoint; touchpoint = touchpoint->next)
{
arg = Fcons (list3i (lrint (touchpoint->x),
lrint (touchpoint->y),
lrint (touchpoint->number)),
arg);
if (touchpoint->frame == f)
arg = Fcons (list3i (lrint (touchpoint->x),
lrint (touchpoint->y),
lrint (touchpoint->number)),
arg);
}
if (source)
@ -24348,6 +24483,31 @@ handle_one_xevent (struct x_display_info *dpyinfo,
}
}
/* Now see if the touchpoint was previously on the tool bar.
If it was, release the tool bar. */
if (!f)
f = x_window_to_frame (dpyinfo, xev->event);
if (f && (FRAME_OUTPUT_DATA (f)->tool_bar_touch_id
== xev->detail))
{
if (f->last_tool_bar_item != -1)
handle_tool_bar_click_with_device (f, xev->event_x,
xev->event_y,
false, 0,
(source
? source->name
: Qnil));
/* Cancel any outstanding mouse highlight. */
note_mouse_highlight (f, -1, -1);
x_flush_dirty_back_buffer_on (f);
/* Now clear the tool bar device. */
FRAME_OUTPUT_DATA (f)->tool_bar_touch_device = 0;
}
goto XI_OTHER;
}
@ -28453,6 +28613,11 @@ x_make_frame_invisible (struct frame *f)
block_input ();
#ifdef HAVE_XINPUT2_2
/* Remove any touch points associated with F. */
xi_unlink_touch_points (f);
#endif
/* Before unmapping the window, update the WM_SIZE_HINTS property to claim
that the current position of the window is user-specified, rather than
program-specified, so that when the window is mapped again, it will be
@ -28658,6 +28823,11 @@ x_free_frame_resources (struct frame *f)
xi_handle_delete_frame (dpyinfo, f);
#endif
#ifdef HAVE_XINPUT2_2
/* Remove any touch points associated with F. */
xi_unlink_touch_points (f);
#endif
/* If a display connection is dead, don't try sending more
commands to the X server. */
if (dpyinfo->display)

View file

@ -257,10 +257,17 @@ struct xi_scroll_valuator_t
struct xi_touch_point_t
{
/* The next touch point in this list. */
struct xi_touch_point_t *next;
/* The touchpoint detail. */
int number;
/* The last known X and Y position of the touchpoint. */
double x, y;
/* The frame associated with this touch point. */
struct frame *frame;
};
#endif
@ -1295,6 +1302,16 @@ struct x_output
VisibilityFullyObscured, but is set to something else in
handle_one_xevent. */
int visibility_state;
#ifdef HAVE_XINPUT2_2
/* The touch ID of the last touch point to have touched the tool
bar. */
int tool_bar_touch_id;
/* The device that last touched the tool bar. 0 if no device
touched the tool bar. */
int tool_bar_touch_device;
#endif
};
enum

View file

@ -746,6 +746,10 @@ it, since the setter is nil."
(format "cd %s" ert-remote-temporary-file-directory))
(eshell-match-command-output "echo $PATH" (regexp-quote remote-path)))))
(ert-deftest esh-var-test/uid-var ()
"Test that $UID is equivalent to (user-uid) for local directories."
(eshell-command-result-equal "echo $UID" (user-uid)))
(ert-deftest esh-var-test/last-status-var-lisp-command ()
"Test using the \"last exit status\" ($?) variable with a Lisp command"
(with-temp-eshell

View file

@ -133,6 +133,20 @@ Name: Multiline Block Comments 4 (bug#60270)
*/
=-=-=
Name: Multiline Block Comments 5 (bug#60270)
=-=
/*
line one
line 2
*/
=-=
/*
line one
line 2
*/
=-=-=
Code:
(lambda ()

View file

@ -0,0 +1,44 @@
Code:
(lambda ()
(setq indent-tabs-mode nil)
(setq java-ts-mode-indent-offset 2)
(java-ts-mode)
(indent-region (point-min) (point-max)))
Point-Char: |
Name: Basic
=-=
public class Basic {
public void basic() {
return;
}
}
=-=-=
Name: Empty Line
=-=
public class EmptyLine {
public void emptyLine() {
|
}
}
=-=-=
Name: Statements
=-=
if (x) {
for (var foo : foos) {
|
}
} else if (y) {
for (int i = 0; x < foos.size(); i++) {
return;
}
} else {
return;
}
=-=-=

View file

@ -0,0 +1,154 @@
Code:
(lambda ()
(java-ts-mode)
(forward-sentence 1))
Point-Char: |
Name: forward-sentence moves over if
=-=
public class Basic {
public void basic() {
|if (x) {
}
log.info("some text: {}", text);
return;
}
}
=-=
public class Basic {
public void basic() {
if (x) {
}|
log.info("some text: {}", text);
return;
}
}
=-=-=
Name: forward-sentence moves over method invocation
=-=
public class Basic {
public void basic() {
|log.info("some text: {}", text);
}
}
=-=
public class Basic {
public void basic() {
log.info("some text: {}", text);|
}
}
=-=-=
Code:
(lambda ()
(java-ts-mode)
(forward-sentence 2))
Name: forward-sentence moves over multiple statements
=-=
public class Basic {
public void basic() {
|return;
return;
}
}
=-=
public class Basic {
public void basic() {
return;
return;|
}
}
=-=-=
Code:
(lambda ()
(java-ts-mode)
(backward-sentence 1))
Name: backward-sentence moves over one statement
=-=
public class Basic {
public void basic() {
return;|
}
}
=-=
public class Basic {
public void basic() {
|return;
}
}
=-=-=
Code:
(lambda ()
(java-ts-mode)
(beginning-of-defun))
Name: beginning-of-defun moves to defun start
=-=
public class Basic {
public void basic() {
return;|
}
}
=-=
public class Basic {
| public void basic() {
return;
}
}
=-=-=
Code:
(lambda ()
(java-ts-mode)
(beginning-of-defun)
(beginning-of-defun))
Name: beginning-of-defun moves to class
=-=
public class Basic {
public void basic() {
return;|
}
}
=-=
|public class Basic {
public void basic() {
return;
}
}
=-=-=
Code:
(lambda ()
(java-ts-mode)
(end-of-defun))
Name: end-of-defun moves to defun end
=-=
public class Basic {
public void basic() {
return;|
}
}
=-=
public class Basic {
public void basic() {
return;
}
|}
=-=-=

View file

@ -0,0 +1,35 @@
;;; java-ts-mode-tests.el --- Tests for Tree-sitter-based Java mode -*- lexical-binding: t; -*-
;; Copyright (C) 2023 Free Software Foundation, Inc.
;; This file is part of GNU Emacs.
;; GNU Emacs is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;; GNU Emacs is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
;;; Code:
(require 'ert)
(require 'ert-x)
(require 'treesit)
(ert-deftest java-ts-mode-test-indentation ()
(skip-unless (treesit-ready-p 'java))
(ert-test-erts-file (ert-resource-file "indent.erts")))
(ert-deftest java-ts-mode-test-movement ()
(skip-unless (treesit-ready-p 'java))
(ert-test-erts-file (ert-resource-file "movement.erts")))
(provide 'java-ts-mode-tests)
;;; java-ts-mode-tests.el ends here

View file

@ -251,6 +251,7 @@ The whitespace before and including \"|\" on each line is removed."
(kill-buffer buf)))))
(ruby-ts-deftest-indent "ruby-method-params-indent.rb")
(ruby-ts-deftest-indent "ruby-block-indent.rb")
(provide 'ruby-ts-mode-tests)

View file

@ -0,0 +1,73 @@
Code:
(lambda ()
(setq indent-tabs-mode nil)
(setq typescript-ts-mode-indent-offset 2)
(typescript-ts-mode)
(indent-region (point-min) (point-max)))
Point-Char: |
Name: Basic indentation
=-=
const foo = () => {
console.log("bar");
if (x) {
return y;
} else if (y) {
return u;
}
return baz.x()
? true
: false;
}
=-=-=
Code:
(lambda ()
(setq indent-tabs-mode nil)
(setq tsx-ts-mode-indent-offset 2)
(tsx-ts-mode)
(indent-region (point-min) (point-max)))
Name: JSX indentation
=-=
const foo = (props) => {
return (
<div>
<div>
<div>
<div>
{
props.foo
? Hello, foo!
: Hello, World!;
}
</div>
</div>
</div>
</div>
);
}
=-=-=
Name: JSX indentation with attributes
=-=
const foo = (props) => {
return (
<div
className={foo}
onClick={() => {
alert('???');
return () => {
return 5+5;
};
}}
>
<p>Some text</p>
</div>
);
}
=-=-=

View file

@ -0,0 +1,31 @@
;;; typescript-ts-mode-tests.el --- Tests for Tree-sitter-based TypeScript mode -*- lexical-binding: t; -*-
;; Copyright (C) 2023 Free Software Foundation, Inc.
;; This file is part of GNU Emacs.
;; GNU Emacs is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;; GNU Emacs is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
;;; Code:
(require 'ert)
(require 'ert-x)
(require 'treesit)
(ert-deftest typescript-ts-mode-test-indentation ()
(skip-unless (treesit-ready-p 'typescript))
(ert-test-erts-file (ert-resource-file "indent.erts")))
(provide 'typescript-ts-mode-tests)
;;; typescript-ts-mode-tests.el ends here