New command tramp-revert-buffer-with-sudo

* doc/misc/tramp.texi (Ad-hoc multi-hops):
Document tramp-file-name-with-method and tramp-revert-buffer-with-sudo.

* etc/NEWS: New command tramp-revert-buffer-with-sudo.

* lisp/net/tramp-cmds.el (dired-advertise, dired-unadvertise): Declare.
(tramp-dired-buffer-p, tramp-remote-process-p): Rename.
(tramp-file-name-with-method): New defcustom.
(tramp-file-name-with-sudo, tramp-revert-buffer-with-sudo): New defuns.
This commit is contained in:
Michael Albinus 2023-09-11 13:51:58 +02:00
parent 38e96bee1f
commit 6e93e76083
3 changed files with 118 additions and 8 deletions

View file

@ -3716,6 +3716,36 @@ containers on the remote host.
@end lisp
@end defopt
A common use case for ad-hoc specifications is to visit a file or a
directory with proper permissions, for example with the @option{sudo}
method. The command @code{tramp-revert-buffer-with-sudo} supports
this.
@deffn Command tramp-revert-buffer-with-sudo
This command shows the current buffer with @option{sudo} permissions.
The buffer must either visit a file, or a directory
(@code{dired-mode}).
@end deffn
@defopt tramp-file-name-with-method
The method @code{tramp-revert-buffer-with-sudo} shows an alternate
buffer. It defaults to @code{sudo}, other valid methods are
@code{su}, @code{doas}, and @code{ksu}.
@lisp
(customize-set-variable 'tramp-file-name-with-method "doas")
@end lisp
@end defopt
These methods apply the user @samp{root} as default. If another user
shall be taken, add a proper rule to the user option
@code{tramp-default-user-alist} (@pxref{Default User}):
@lisp
(add-to-list 'tramp-default-user-alist '("sudo" "remotehost" "admin"))
@end lisp
@node Home directories
@section Expanding @file{~} to home directory

View file

@ -483,6 +483,13 @@ be attempted at the end of a multi-hop chain. This allows completion
candidates to include a list of, for example, containers running on a
remote docker host.
+++
*** New command 'tramp-revert-buffer-with-sudo'.
It reverts the current buffer to visit with "sudo" permissions. The
buffer must either visit a file, or it must run 'dired-mode'. Another
method but "sudo" can be configured with user option
'tramp-file-name-with-method'.
** EWW
+++
@ -748,7 +755,7 @@ This can help avoid some awkward skip conditions. For example
'(skip-unless (not noninteractive))' can be changed to the easier
to read '(skip-when noninteractive)'.
** checkdoc
** Checkdoc
---
*** New checkdock warning if not using lexical-binding.
@ -756,7 +763,7 @@ Checkdoc now warns if the first line of an Emacs Lisp file does not
end with a "-*- lexical-binding: t -*-" cookie. Customize the user
option 'checkdoc-lexical-binding-flag' to nil to disable this warning.
** url
** URL
+++
*** 'url-gateway-broken-resolution' is now obsolete.
@ -787,7 +794,7 @@ files.
+++
** New global minor mode 'minibuffer-regexp-mode'.
This is a minor mode for editing regular expressions in the minibuffer.
It highlight parens via show-paren-mode and blink-matching-paren in
It highlights parens via show-paren-mode and blink-matching-paren in
a user-friendly way, avoids reporting alleged paren mismatches and makes
sexp navigation more intuitive.
@ -915,7 +922,7 @@ See the "(elisp) Porting Old Advice" node for help converting them
to use 'advice-add' or 'define-advice' instead.
** 'cl-old-struct-compat-mode' is marked as obsolete.
You may need to recompile our code if it was compiled with Emacs<24.3.
You may need to recompile our code if it was compiled with Emacs < 24.3.
+++
** New macro 'static-if' for conditional evaluation of code.

View file

@ -31,6 +31,8 @@
(require 'tramp)
;; Pacify byte-compiler.
(declare-function dired-advertise "dired")
(declare-function dired-unadvertise "dired")
(declare-function mml-mode "mml")
(declare-function mml-insert-empty-tag "mml")
(declare-function reporter-dump-variable "reporter")
@ -75,6 +77,8 @@ SYNTAX can be one of the symbols `default' (default),
(when (tramp-tramp-file-p (tramp-get-default-directory x)) x))
(buffer-list))))
;;; Cleanup
;;;###tramp-autoload
(defvar tramp-cleanup-connection-hook nil
"List of functions to be called after Tramp connection is cleaned up.
@ -221,13 +225,13 @@ functions are called with `current-buffer' set."
(add-hook 'tramp-cleanup-some-buffers-hook
#'buffer-file-name)
(defun tramp-cleanup-dired-buffer-p ()
(defun tramp-dired-buffer-p ()
"Return t if current buffer runs `dired-mode'."
(declare (tramp-suppress-trace t))
(derived-mode-p 'dired-mode))
(add-hook 'tramp-cleanup-some-buffers-hook
#'tramp-cleanup-dired-buffer-p)
#'tramp-dired-buffer-p)
(defvar tramp-tainted-remote-process-buffers nil
"List of process buffers to be cleaned up.")
@ -256,12 +260,12 @@ functions are called with `current-buffer' set."
(remove-hook 'kill-buffer-hook
#'tramp-delete-tainted-remote-process-buffer-function)))
(defun tramp-cleanup-remote-process-p ()
(defun tramp-remote-process-p ()
"Return t if current buffer belongs to a remote process."
(memq (current-buffer) tramp-tainted-remote-process-buffers))
(add-hook 'tramp-cleanup-some-buffers-hook
#'tramp-cleanup-remote-process-p)
#'tramp-remote-process-p)
;;;###tramp-autoload
(defun tramp-cleanup-some-buffers ()
@ -288,6 +292,8 @@ non-nil."
(let ((tramp-cleanup-some-buffers-hook '(tramp-compat-always)))
(tramp-cleanup-some-buffers)))
;;; Rename
(defcustom tramp-default-rename-alist nil
"Default target for renaming remote buffer file names.
This is an alist of cons cells (SOURCE . TARGET). The first
@ -552,6 +558,73 @@ For details, see `tramp-rename-files'."
(function-put
#'tramp-rename-these-files 'completion-predicate #'tramp-command-completion-p)
;;; Run as sudo
(defcustom tramp-file-name-with-method "sudo"
"Which method to be used in `tramp-file-name-with-sudo'."
:group 'tramp
:version "30.1"
:type '(choice (const "su")
(const "sudo")
(const "doas")
(const "ksu")))
(defun tramp-file-name-with-sudo (filename)
"Convert FILENAME into a multi-hop file name with \"sudo\".
An alternative method could be chosen with `tramp-file-name-with-method'."
(setq filename (expand-file-name filename))
(if (tramp-tramp-file-p filename)
(with-parsed-tramp-file-name filename nil
(cond
;; Remote file with proper method.
((string-equal method tramp-file-name-with-method)
filename)
;; Remote file on the local host.
((and
(stringp tramp-local-host-regexp) (stringp host)
(string-match-p tramp-local-host-regexp host))
(tramp-make-tramp-file-name
(make-tramp-file-name
:method tramp-file-name-with-method :localname localname)))
;; Remote file with multi-hop capable method..
((tramp-multi-hop-p v)
(tramp-make-tramp-file-name
(make-tramp-file-name
:method (tramp-find-method tramp-file-name-with-method nil host)
:user (tramp-find-user tramp-file-name-with-method nil host)
:host (tramp-find-host tramp-file-name-with-method nil host)
:localname localname :hop (tramp-make-tramp-hop-name v))))
;; Other remote file.
(t (tramp-user-error v "Multi-hop with `%s' not applicable" method))))
;; Local file.
(tramp-make-tramp-file-name
(make-tramp-file-name
:method tramp-file-name-with-method :localname filename))))
;;;###tramp-autoload
(defun tramp-revert-buffer-with-sudo ()
"Revert current buffer to visit with \"sudo\" permissions.
An alternative method could be chosen with `tramp-file-name-with-method'.
If the buffer visits a file, the file is replaced.
If the buffer runs `dired', the buffer is reverted."
(interactive)
(cond
((buffer-file-name)
(find-alternate-file (tramp-file-name-with-sudo (buffer-name))))
((tramp-dired-buffer-p)
(dired-unadvertise (expand-file-name default-directory))
(setq default-directory (tramp-file-name-with-sudo default-directory)
list-buffers-directory
(tramp-file-name-with-sudo list-buffers-directory))
(if (consp dired-directory)
(setcar
dired-directory (tramp-file-name-with-sudo (car dired-directory)))
(setq dired-directory (tramp-file-name-with-sudo dired-directory)))
(dired-advertise)
(revert-buffer))))
;;; Recompile on ELPA
;; This function takes action since Emacs 28.1, when
;; `read-extended-command-predicate' is set to
;; `command-completion-default-include-p'.