Merge from origin/emacs-31

f89ff62367 Extend Tramp external operations
4dea6ea36b markdown-ts-mode: fix duplicated menu entries (bug#81201)
9cad2da66e ; Fix last change.
cd84bd6a0c vc-dir-recompute-file-state: Change directory to DEF-DIR
47bdbc8d85 Restore "interactive" when describing functions
1a5d9a4be3 Inhibit follow-link via `mouse-1' on the tab-bar (bug#81036)
c94d58ddbf Fix the tab close button appearance when clicking (bug#76...
a21614d4d6 ; Skip one vc-dir test on MS-Windows
abddd2075a ; Fix last change to vc-dir-recompute-file-state.
89bda8736a Install images with info documentation (bug#81204)
466789b511 vc-dir-recompute-file-state: Return nil state for nonexis...
This commit is contained in:
Sean Whitton 2026-06-11 16:12:15 +01:00
commit f836632aee
10 changed files with 187 additions and 75 deletions

View file

@ -808,7 +808,7 @@ install-info: info
done; \ done; \
(cd "$${thisdir}"; \ (cd "$${thisdir}"; \
${INSTALL_INFO} --info-dir="$(DESTDIR)${infodir}" "$(DESTDIR)${infodir}/$$elt"); \ ${INSTALL_INFO} --info-dir="$(DESTDIR)${infodir}" "$(DESTDIR)${infodir}/$$elt"); \
cp elisp_type_hierarchy* $(DESTDIR)${infodir}/; \ cp *.jpg *.png $(DESTDIR)${infodir}/; \
done; \ done; \
fi fi

View file

@ -6973,7 +6973,7 @@ If the same @var{function} shall be used for different @value{tramp}
backends, @code{tramp-add-external-operation} must be called for every backends, @code{tramp-add-external-operation} must be called for every
backend, respectively. backend, respectively.
The optional argument @var{arg-type} specisfies, which argument of The optional argument @var{arg-type} specifies, which argument of
@var{operation} shall be used in order to determine, whether the @var{operation} shall be used in order to determine, whether the
handler @var{function} should be called. It can be handler @var{function} should be called. It can be
@ -6988,6 +6988,10 @@ checked. This is the default, if @var{arg-type} is @code{nil}.
@item @code{process}@* @item @code{process}@*
@code{default-directory} of the process buffer of the first argument @code{default-directory} of the process buffer of the first argument
of @var{operation}, a process, is the remote file name to be checked. of @var{operation}, a process, is the remote file name to be checked.
@item @code{tramp-file-name}@*
The @code{tramp-file-name} structure of the first argument of
@var{operation} is the remote file name to be checked.
@end itemize @end itemize
If the first argument of @var{operation} is nil, If the first argument of @var{operation} is nil,
@ -7015,6 +7019,26 @@ The example above could be changed like this:
@end lisp @end lisp
@end defun @end defun
@defun tramp-external-operation-p operation backend
This checks, whether @value{tramp}'s backend @var{backend} supports
external @var{operation}. It returns the function registered as
handler, or @code{nil}. Example:
@lisp
@group
(tramp-external-operation-p
#'my-test-operation 'tramp-sh)
@result{} my-handle-test-operation
@end group
@group
(tramp-external-operation-p
#'my-test-operation 'tramp-gvfs)
@result{} nil
@end group
@end lisp
@end defun
@defun tramp-remove-external-operation operation backend @defun tramp-remove-external-operation operation backend
The handler for @var{operation}, added by The handler for @var{operation}, added by
@code{tramp-add-external-operation}, is removed from @var{backend}. @code{tramp-add-external-operation}, is removed from @var{backend}.

View file

@ -1184,7 +1184,8 @@ Returns a list of the form (REAL-FUNCTION DEF ALIASED REAL-DEF)."
;; FIXME: If someday Emacs has a function type symbol ;; FIXME: If someday Emacs has a function type symbol
;; like `unicode-function' or `hour-function', this ;; like `unicode-function' or `hour-function', this
;; will produce an ungrammatical string (bug#79469). ;; will produce an ungrammatical string (bug#79469).
(concat (if (string-match-p "\\`[aeiou]" (symbol-name type)) (concat (if (and (equal beg "a ")
(string-match-p "\\`[aeiou]" typ-str))
"an " "an "
beg) beg)
typ-str)))))) typ-str))))))

View file

@ -1864,18 +1864,26 @@ click is the local or global binding of that event.
- Otherwise, the mouse-1 event is translated into a mouse-2 event - Otherwise, the mouse-1 event is translated into a mouse-2 event
at the same position." at the same position."
(let ((action (let* ((area (and (consp pos) (posn-area pos)))
(action
(and (or (not (consp pos)) (and (or (not (consp pos))
mouse-1-click-in-non-selected-windows mouse-1-click-in-non-selected-windows
(eq (selected-window) (posn-window pos))) (eq (selected-window) (posn-window pos)))
(or (mouse-posn-property pos 'follow-link) (or (mouse-posn-property pos 'follow-link)
(let ((area (posn-area pos)))
(when area (when area
(key-binding (vector area 'follow-link) nil t pos))) (key-binding (vector area 'follow-link) nil t pos))
(key-binding [follow-link] nil t pos))))) (key-binding [follow-link] nil t pos)))))
(cond (cond
((eq action 'mouse-face) ((eq action 'mouse-face)
(and (mouse-posn-property pos 'mouse-face) t)) ;; Inhibit follow-link when `mouse-1' is clicked on the tab-bar to
;; prevent misdirected clicks in `dired-mode'. This does not prevent
;; remapping `mouse-1' to `mouse-2' on the tab-bar. See bug#49247
;; bug#81036.
;; FIXME: The tab-bar is not associated with a buffer so a better fix
;; might be not to honor the current buffer's keymap when considering
;; tab-bar mouse clicks,
(and (not (eq area 'tab-bar))
(mouse-posn-property pos 'mouse-face) t))
((functionp action) ((functionp action)
;; FIXME: This seems questionable if the click is not in a buffer. ;; FIXME: This seems questionable if the click is not in a buffer.
;; Should we instead decide that `action' takes a `posn'? ;; Should we instead decide that `action' takes a `posn'?

View file

@ -2447,6 +2447,8 @@ symbol
checked. checked.
- `process': `default-directory' of the process buffer of the first - `process': `default-directory' of the process buffer of the first
argument of OPERATION is the remote file name to be checked. argument of OPERATION is the remote file name to be checked.
- `tramp-file-name': the first argument of OPERATION, a
`tramp-file-name' structure, is the remote file name to be checked.
If the first argument of OPERATION is nil, `default-directory' is the If the first argument of OPERATION is nil, `default-directory' is the
remote file name to be checked in case of `file' and `process'. remote file name to be checked in case of `file' and `process'.
@ -2500,8 +2502,10 @@ Must be handled by the callers."
(if (and (stringp (nth 0 args)) (file-name-absolute-p (nth 0 args))) (if (and (stringp (nth 0 args)) (file-name-absolute-p (nth 0 args)))
(nth 0 args) (nth 0 args)
default-directory)) default-directory))
;; STRING FILE. ;; STRING FILE.
((eq operation 'make-symbolic-link) (nth 1 args)) ((eq operation 'make-symbolic-link) (nth 1 args))
;; FILE DIRECTORY resp FILE1 FILE2. ;; FILE DIRECTORY resp FILE1 FILE2.
((memq operation ((memq operation
'(add-name-to-file copy-directory copy-file '(add-name-to-file copy-directory copy-file
@ -2512,23 +2516,27 @@ Must be handled by the callers."
((tramp-tramp-file-p (nth 0 args)) (nth 0 args)) ((tramp-tramp-file-p (nth 0 args)) (nth 0 args))
((file-name-absolute-p (nth 1 args)) (nth 1 args)) ((file-name-absolute-p (nth 1 args)) (nth 1 args))
(t default-directory))) (t default-directory)))
;; FILE DIRECTORY resp FILE1 FILE2. ;; FILE DIRECTORY resp FILE1 FILE2.
((eq operation 'expand-file-name) ((eq operation 'expand-file-name)
(cond (cond
((file-name-absolute-p (nth 0 args)) (nth 0 args)) ((file-name-absolute-p (nth 0 args)) (nth 0 args))
((tramp-tramp-file-p (nth 1 args)) (nth 1 args)) ((tramp-tramp-file-p (nth 1 args)) (nth 1 args))
(t default-directory))) (t default-directory)))
;; START END FILE. ;; START END FILE.
((eq operation 'write-region) ((eq operation 'write-region)
(if (file-name-absolute-p (nth 2 args)) (if (file-name-absolute-p (nth 2 args))
(nth 2 args) (nth 2 args)
default-directory)) default-directory))
;; BUFFER. ;; BUFFER.
((memq operation ((memq operation
'(make-auto-save-file-name '(make-auto-save-file-name
set-visited-file-modtime verify-visited-file-modtime)) set-visited-file-modtime verify-visited-file-modtime))
(buffer-file-name (buffer-file-name
(if (bufferp (nth 0 args)) (nth 0 args) (current-buffer)))) (if (bufferp (nth 0 args)) (nth 0 args) (current-buffer))))
;; COMMAND. ;; COMMAND.
((or ((or
(memq operation (memq operation
@ -2541,6 +2549,7 @@ Must be handled by the callers."
(eq (alist-get operation tramp-file-name-for-operation-external) (eq (alist-get operation tramp-file-name-for-operation-external)
'default-directory)) 'default-directory))
default-directory) default-directory)
;; PROC or BUFFER. ;; PROC or BUFFER.
((or ((or
(memq operation '(file-notify-rm-watch file-notify-valid-p)) (memq operation '(file-notify-rm-watch file-notify-valid-p))
@ -2557,16 +2566,25 @@ Must be handled by the callers."
(or (get-process (nth 0 args)) (get-buffer (nth 0 args))))))) (or (get-process (nth 0 args)) (get-buffer (nth 0 args)))))))
(tramp-get-default-directory buf)) (tramp-get-default-directory buf))
"")) ""))
;; VEC. ;; VEC.
((memq operation ((or
(memq operation
'(tramp-get-home-directory tramp-get-remote-gid '(tramp-get-home-directory tramp-get-remote-gid
tramp-get-remote-groups tramp-get-remote-uid)) tramp-get-remote-groups tramp-get-remote-uid))
(eq (alist-get operation tramp-file-name-for-operation-external)
'tramp-file-name))
(or
(and (tramp-file-name-p (nth 0 args))
(tramp-make-tramp-file-name (nth 0 args))) (tramp-make-tramp-file-name (nth 0 args)))
""))
;; A function. ;; A function.
((functionp (alist-get operation tramp-file-name-for-operation-external)) ((functionp (alist-get operation tramp-file-name-for-operation-external))
(apply (apply
(alist-get operation tramp-file-name-for-operation-external) (alist-get operation tramp-file-name-for-operation-external)
operation args)) operation args))
;; Unknown file primitive. ;; Unknown file primitive.
(t (unless (memq 'remote-file-error debug-ignored-errors) (t (unless (memq 'remote-file-error debug-ignored-errors)
(tramp-error (tramp-error
@ -2601,17 +2619,17 @@ OPERATION must not be one of the magic operations listed in Info
node `(elisp) Magic File Names'. FUNCTION must have the same argument node `(elisp) Magic File Names'. FUNCTION must have the same argument
list as OPERATION. BACKEND, a symbol, must be one of the Tramp backend list as OPERATION. BACKEND, a symbol, must be one of the Tramp backend
packages like `tramp-sh' (except `tramp-ftp'). ARG-TYPE is either packages like `tramp-sh' (except `tramp-ftp'). ARG-TYPE is either
`file' (the default), `default-directory', `process' or a function `file' (the default), `default-directory', `process', `tramp-file-name',
symbol. It describes the type of the OPERATION argument to be checked. or a function symbol. It describes the type of the OPERATION argument
See the docstring of `tramp-file-name-for-operation-external' for its to be checked. See the docstring of
meaning." `tramp-file-name-for-operation-external' for its meaning."
(require backend) (require backend)
(when-let* ((fnha (when-let* ((fnha
(intern-soft (intern-soft
(concat (symbol-name backend) "-file-name-handler-alist"))) (concat (symbol-name backend) "-file-name-handler-alist")))
((boundp fnha)) ((boundp fnha))
(arg-type (or arg-type 'file))) (arg-type (or arg-type 'file)))
(unless (or (memq arg-type '(file default-directory process)) (unless (or (memq arg-type '(file default-directory process tramp-file-name))
(functionp arg-type)) (functionp arg-type))
(tramp-error nil 'remote-file-error "Unknown arg type: %s" arg-type)) (tramp-error nil 'remote-file-error "Unknown arg type: %s" arg-type))
;; Make BACKEND aware of the new operation. ;; Make BACKEND aware of the new operation.
@ -2635,6 +2653,15 @@ meaning."
(apply orig-fun args))) (apply orig-fun args)))
`((name . ,(concat "tramp-advice-" (symbol-name operation)))))))) `((name . ,(concat "tramp-advice-" (symbol-name operation))))))))
(defun tramp-external-operation-p (operation backend)
"Check, whether Tramp BACKEND supports external OPERATION.
It returns the function registered as handler, or nil."
(and-let* ((fnha
(intern-soft
(concat (symbol-name backend) "-file-name-handler-alist")))
((boundp fnha))
((alist-get operation (symbol-value fnha))))))
(defun tramp-remove-external-operation (operation backend) (defun tramp-remove-external-operation (operation backend)
"Remove OPERATION from Tramp BACKEND as handler for OPERATION. "Remove OPERATION from Tramp BACKEND as handler for OPERATION.
OPERATION must not be one of the magic operations listed in Info OPERATION must not be one of the magic operations listed in Info
@ -4264,8 +4291,7 @@ Let-bind it when necessary.")
(tramp-get-connection-property vec "~")))) (tramp-get-connection-property vec "~"))))
(when home-dir (when home-dir
(setq home-dir (setq home-dir
(tramp-compat-funcall (tramp-compat-funcall 'directory-abbrev-apply
'directory-abbrev-apply
(tramp-make-tramp-file-name vec home-dir)))) (tramp-make-tramp-file-name vec home-dir))))
;; If any elt of `directory-abbrev-alist' matches this name, ;; If any elt of `directory-abbrev-alist' matches this name,
;; abbreviate accordingly. ;; abbreviate accordingly.
@ -4864,8 +4890,7 @@ existing) are returned."
(setq remote-copy (tramp-make-tramp-temp-file v)) (setq remote-copy (tramp-make-tramp-temp-file v))
;; This is defined in tramp-sh.el. Let's assume ;; This is defined in tramp-sh.el. Let's assume
;; this is loaded already. ;; this is loaded already.
(tramp-compat-funcall (tramp-compat-funcall 'tramp-send-command
'tramp-send-command
v v
(cond (cond
((and beg end) ((and beg end)
@ -5565,12 +5590,10 @@ processes."
(tramp-compat-make-temp-name)))) (tramp-compat-make-temp-name))))
(options (options
(when sh-file-name-handler-p (when sh-file-name-handler-p
(tramp-compat-funcall (tramp-compat-funcall 'tramp-ssh-controlmaster-options v)))
'tramp-ssh-controlmaster-options v)))
(device (device
(when adb-file-name-handler-p (when adb-file-name-handler-p
(tramp-compat-funcall (tramp-compat-funcall 'tramp-adb-get-device v)))
'tramp-adb-get-device v)))
(pta (unless (eq connection-type 'pipe) "-t")) (pta (unless (eq connection-type 'pipe) "-t"))
login-args p) login-args p)
@ -7475,8 +7498,7 @@ name of a process or buffer, or nil to default to the current buffer."
;; This is for tramp-sh.el. Other backends do not support this (yet). ;; This is for tramp-sh.el. Other backends do not support this (yet).
;; Not all "kill" implementations support process groups by ;; Not all "kill" implementations support process groups by
;; negative pid, so we try both variants. ;; negative pid, so we try both variants.
(tramp-compat-funcall (tramp-compat-funcall 'tramp-send-command
'tramp-send-command
(process-get proc 'tramp-vector) (process-get proc 'tramp-vector)
(format "(\\kill -2 -%d || \\kill -2 %d) 2>%s" (format "(\\kill -2 -%d || \\kill -2 %d) 2>%s"
pid pid pid pid
@ -7531,8 +7553,7 @@ SIGCODE may be an integer, or a symbol whose name is a signal name."
(tramp-message (tramp-message
vec 5 "Send signal %s to process %s with pid %s" sigcode process pid) vec 5 "Send signal %s to process %s with pid %s" sigcode process pid)
;; This is for tramp-sh.el. Other backends do not support this (yet). ;; This is for tramp-sh.el. Other backends do not support this (yet).
(if (tramp-compat-funcall (if (tramp-compat-funcall 'tramp-send-command-and-check
'tramp-send-command-and-check
vec (format "\\kill -%s %d" sigcode pid)) vec (format "\\kill -%s %d" sigcode pid))
0 -1)))) 0 -1))))

View file

@ -5116,7 +5116,6 @@ On a heading, call `outline-cycle'. Otherwise do nothing."
:doc "Keymap for `markdown-ts-code-block-in-context-mode'. :doc "Keymap for `markdown-ts-code-block-in-context-mode'.
These override keys in `markdown-ts-mode-map' to support executing their These override keys in `markdown-ts-mode-map' to support executing their
commands in a code-block context." commands in a code-block context."
:parent markdown-ts-mode-map
:menu nil :menu nil
"M-." #'markdown-ts--code-block-xref-find-definitions "M-." #'markdown-ts--code-block-xref-find-definitions
"TAB" #'indent-for-tab-command "TAB" #'indent-for-tab-command
@ -5129,7 +5128,6 @@ commands in a code-block context."
:doc "Keymap for `markdown-ts-in-table-mode'. :doc "Keymap for `markdown-ts-in-table-mode'.
These override keys in `markdown-ts-mode-map' to support executing their These override keys in `markdown-ts-mode-map' to support executing their
commands in a table context." commands in a table context."
:parent markdown-ts-mode-map
:menu nil :menu nil
"<return>" #'markdown-ts-table-next-row "<return>" #'markdown-ts-table-next-row
"S-<return>" #'markdown-ts-table-previous-row "S-<return>" #'markdown-ts-table-previous-row

View file

@ -1270,16 +1270,20 @@ that file."
(defun vc-dir-recompute-file-state (fname def-dir) (defun vc-dir-recompute-file-state (fname def-dir)
"Compute state of FNAME known to live inside DEF-DIR." "Compute state of FNAME known to live inside DEF-DIR."
(let* ((file-short (file-relative-name fname def-dir)) (let ((fname-short (file-relative-name fname def-dir)))
(_remove-me-when-CVS-works
(when (eq vc-dir-backend 'CVS) (when (eq vc-dir-backend 'CVS)
;; FIXME: Warning: UGLY HACK. The CVS backend caches the state ;; FIXME: Warning: UGLY HACK. The CVS backend caches the state
;; info, this forces the backend to update it. ;; info, this forces the backend to update it.
(vc-call-backend vc-dir-backend 'registered fname))) (vc-call-backend vc-dir-backend 'registered fname))
(state (vc-call-backend vc-dir-backend 'state fname)) (let* ((default-directory def-dir)
(state (vc-call-backend vc-dir-backend 'state fname-short))
(extra (vc-call-backend vc-dir-backend (extra (vc-call-backend vc-dir-backend
'status-fileinfo-extra fname))) 'status-fileinfo-extra fname-short)))
(list file-short state extra))) ;; Ensure we return a nil state if the file does not exist and is
;; not tracked so that it disappears from VC-Dir (bug#81191).
(if (and (eq state 'up-to-date) (not (file-exists-p fname)))
(list fname-short nil nil)
(list fname-short state extra)))))
(defun vc-dir-find-child-files (dirname) (defun vc-dir-find-child-files (dirname)
;; Give a DIRNAME string return the list of all child files shown in ;; Give a DIRNAME string return the list of all child files shown in
@ -1338,6 +1342,7 @@ that file."
(vc-dir-resync-directory-files file) (vc-dir-resync-directory-files file)
(vc-dir--set-header ddir)) (vc-dir--set-header ddir))
(let* ((complete-state (let* ((complete-state
;; Pass two truenames (bug#80803, bug#80967).
(vc-dir-recompute-file-state file (vc-dir-recompute-file-state file
(file-truename ddir))) (file-truename ddir)))
(state (cadr complete-state))) (state (cadr complete-state)))

View file

@ -15321,16 +15321,24 @@ handle_tab_bar_click (struct frame *f, int x, int y, bool down_p,
if (down_p) if (down_p)
{ {
/* Show the clicked button in pressed state. */ /* Show the clicked button in pressed state, but only when
the click was on the close button. Clicking elsewhere on
the tab should not change the close button's appearance,
so just keep the ordinary mouse-face highlight. */
if (!NILP (Vmouse_highlight)) if (!NILP (Vmouse_highlight))
show_mouse_face (hlinfo, DRAW_IMAGE_SUNKEN, true); show_mouse_face (hlinfo, close_p ? DRAW_IMAGE_SUNKEN : DRAW_MOUSE_FACE,
true);
f->last_tab_bar_item = prop_idx; /* record the pressed tab */ f->last_tab_bar_item = prop_idx; /* record the pressed tab */
} }
else else
{ {
/* Show item in released state. */ /* Show item in released state. Only change the close button's
appearance when the click was on it. Elsewhere keep the
ordinary mouse-face highlight to avoid the close button
blinking on release. */
if (!NILP (Vmouse_highlight)) if (!NILP (Vmouse_highlight))
show_mouse_face (hlinfo, DRAW_IMAGE_RAISED, true); show_mouse_face (hlinfo, close_p ? DRAW_IMAGE_RAISED : DRAW_MOUSE_FACE,
true);
f->last_tab_bar_item = -1; f->last_tab_bar_item = -1;
} }

View file

@ -8920,6 +8920,9 @@ process sentinels. They shall not disturb each other."
(intern (intern
(string-remove-suffix (string-remove-suffix
"-file-name-handler" (symbol-name file-name-handler))))) "-file-name-handler" (symbol-name file-name-handler)))))
;; Cleanup.
(tramp-remove-external-operation #'tramp--test-operation backend)
(tramp-remove-external-operation #'process-id backend)
;; There is no backend specific code. ;; There is no backend specific code.
(should-not (should-not
@ -8950,6 +8953,9 @@ process sentinels. They shall not disturb each other."
;; This doesn't hurt. ;; This doesn't hurt.
(tramp-add-external-operation (tramp-add-external-operation
#'tramp--test-operation #'tramp--handle-test-operation backend 'file) #'tramp--test-operation #'tramp--handle-test-operation backend 'file)
(should
(eq #'tramp--handle-test-operation
(tramp-external-operation-p #'tramp--test-operation backend)))
;; The backend specific function is called. ;; The backend specific function is called.
(should (should
@ -8977,6 +8983,7 @@ process sentinels. They shall not disturb each other."
(tramp-remove-external-operation #'tramp--test-operation backend) (tramp-remove-external-operation #'tramp--test-operation backend)
;; There is no backend specific code. ;; There is no backend specific code.
(should-not (tramp-external-operation-p #'tramp--test-operation backend))
(should-not (should-not
(string-equal (tramp--test-operation ert-remote-temporary-file-directory) (string-equal (tramp--test-operation ert-remote-temporary-file-directory)
(tramp--handle-test-operation (tramp--handle-test-operation
@ -9004,6 +9011,9 @@ process sentinels. They shall not disturb each other."
(tramp-add-external-operation (tramp-add-external-operation
#'tramp--test-operation #'tramp--handle-test-operation #'tramp--test-operation #'tramp--handle-test-operation
backend 'default-directory) backend 'default-directory)
(should
(eq #'tramp--handle-test-operation
(tramp-external-operation-p #'tramp--test-operation backend)))
;; The backend specific function is called. ;; The backend specific function is called.
(let ((default-directory ert-remote-temporary-file-directory)) (let ((default-directory ert-remote-temporary-file-directory))
@ -9017,6 +9027,7 @@ process sentinels. They shall not disturb each other."
(tramp-remove-external-operation #'tramp--test-operation backend) (tramp-remove-external-operation #'tramp--test-operation backend)
;; There is no backend specific code. ;; There is no backend specific code.
(should-not (tramp-external-operation-p #'tramp--test-operation backend))
(let ((default-directory ert-remote-temporary-file-directory)) (let ((default-directory ert-remote-temporary-file-directory))
(should-not (should-not
(string-equal (tramp--test-operation) (string-equal (tramp--test-operation)
@ -9048,16 +9059,48 @@ process sentinels. They shall not disturb each other."
(should (natnump (setq id (process-id proc)))) (should (natnump (setq id (process-id proc))))
(tramp-add-external-operation (tramp-add-external-operation
#'process-id #'tramp--handle-process-id backend 'process) #'process-id #'tramp--handle-process-id backend 'process)
(should
(eq #'tramp--handle-process-id
(tramp-external-operation-p #'process-id backend)))
(should (= (process-id proc) (1+ id)))) (should (= (process-id proc) (1+ id))))
;; Cleanup. ;; Cleanup.
(tramp-remove-external-operation #'process-id backend) (tramp-remove-external-operation #'process-id backend)
(should-not (tramp-external-operation-p #'process-id backend))
(ignore-errors (delete-process proc))))) (ignore-errors (delete-process proc)))))
;; Test `tramp-file-name' arg type.
(tramp-add-external-operation
#'tramp--test-operation #'tramp--handle-test-operation
backend 'tramp-file-name)
(should
(eq #'tramp--handle-test-operation
(tramp-external-operation-p #'tramp--test-operation backend)))
;; The backend specific function is called.
(should
(string-equal (tramp--test-operation tramp-test-vec)
(tramp--handle-test-operation tramp-test-vec)))
(let ((vec (copy-tramp-file-name tramp-test-vec)))
(setf (tramp-file-name-method vec) (if (tramp--test-sh-p) "sftp" "sudo"))
(should-not
(string-equal (tramp--test-operation vec)
(tramp--handle-test-operation vec))))
(tramp-remove-external-operation #'tramp--test-operation backend)
;; There is no backend specific code.
(should-not (tramp-external-operation-p #'tramp--test-operation backend))
(should-not
(string-equal (tramp--test-operation tramp-test-vec)
(tramp--handle-test-operation tramp-test-vec)))
;; Test function arg type. ;; Test function arg type.
(tramp-add-external-operation (tramp-add-external-operation
#'tramp--test-operation #'tramp--handle-test-operation #'tramp--test-operation #'tramp--handle-test-operation
backend #'tramp--test-operation-file-name-for-operation) backend #'tramp--test-operation-file-name-for-operation)
(should
(eq #'tramp--handle-test-operation
(tramp-external-operation-p #'tramp--test-operation backend)))
;; The backend specific function is called. ;; The backend specific function is called.
(let ((default-directory ert-remote-temporary-file-directory)) (let ((default-directory ert-remote-temporary-file-directory))
@ -9071,6 +9114,7 @@ process sentinels. They shall not disturb each other."
(tramp-remove-external-operation #'tramp--test-operation backend) (tramp-remove-external-operation #'tramp--test-operation backend)
;; There is no backend specific code. ;; There is no backend specific code.
(should-not (tramp-external-operation-p #'tramp--test-operation backend))
(let ((default-directory ert-remote-temporary-file-directory)) (let ((default-directory ert-remote-temporary-file-directory))
(should-not (should-not
(string-equal (tramp--test-operation) (string-equal (tramp--test-operation)

View file

@ -253,6 +253,8 @@
(ert-deftest vc-test-vc-dir-on-symlink () (ert-deftest vc-test-vc-dir-on-symlink ()
"Test VC-Dir on a symlink to a repository. "Test VC-Dir on a symlink to a repository.
See bug#80803 and bug#80967." See bug#80803 and bug#80967."
;; Git for Windows could fail in a symlinked tree.
(skip-when (eq system-type 'windows-nt))
(skip-unless (executable-find vc-git-program)) (skip-unless (executable-find vc-git-program))
(vc-test--with-author-identity 'Git (vc-test--with-author-identity 'Git
(let ((vc-handled-backends '(Git))) (let ((vc-handled-backends '(Git)))
@ -290,10 +292,11 @@ See bug#80803 and bug#80967."
(basic-save-buffer)) (basic-save-buffer))
(dolist (buf (list truename-dir symlink-dir)) (dolist (buf (list truename-dir symlink-dir))
(with-current-buffer buf (with-current-buffer buf
(should (equal (vc-dir-fileinfo->name (let ((data (ewoc-data (ewoc-nth vc-ewoc 1))))
(ewoc-data (should (equal (vc-dir-fileinfo->name data)
(ewoc-nth vc-ewoc 1))) (file-name-nondirectory file)))
(file-name-nondirectory file)))))))))) (should (equal (vc-dir-fileinfo->state data)
'edited))))))))))
(provide 'vc-test-misc) (provide 'vc-test-misc)
;;; vc-test-misc.el ends here ;;; vc-test-misc.el ends here