From 24ffcbb3da9a010cf564bb496af3f5ce0b805f17 Mon Sep 17 00:00:00 2001 From: Michael Albinus Date: Fri, 14 Mar 2025 16:31:51 +0100 Subject: [PATCH] Improve tramp-*-with-sudo commands * doc/emacs/dired.texi (Dired Visiting): Add tramp-dired-find-file-with-sudo. * doc/emacs/files.texi (Reverting): Add tramp-revert-buffer-with-sudo. * doc/misc/tramp.texi (Ad-hoc multi-hops): Extend wrt `tramp-*-with-sudo' commands. * etc/NEWS: Add tramp-dired-find-file-with-sudo. Fix typos. * lisp/bindings.el (ctl-x-x-map): * lisp/dired.el (dired-mode-map): Add "@" binding. (Bug#76974) * lisp/net/tramp-cmds.el (dired-get-file-for-visit): Declare. (with-tramp-file-name-with-method): New macro. (tramp-revert-buffer-with-sudo): Autoload. Preserve position. Use `with-tramp-file-name-with-method'. (tramp-dired-find-file-with-sudo): New command. --- doc/emacs/dired.texi | 8 +++++ doc/emacs/files.texi | 9 +++++ doc/misc/tramp.texi | 26 ++++++++++----- etc/NEWS | 76 ++++++++++++++++++++++++------------------ lisp/bindings.el | 3 +- lisp/dired.el | 1 + lisp/net/tramp-cmds.el | 55 +++++++++++++++++++++--------- 7 files changed, 120 insertions(+), 58 deletions(-) diff --git a/doc/emacs/dired.texi b/doc/emacs/dired.texi index 07142e71713..f52b001c121 100644 --- a/doc/emacs/dired.texi +++ b/doc/emacs/dired.texi @@ -460,6 +460,14 @@ View the file described on the current line, with View mode (@code{dired-view-file}). View mode provides convenient commands to navigate the buffer but forbids changing it; @xref{View Mode}. +@item @@ +@kindex @@ @r{(Dired)} +@findex tramp-dired-find-file-with-sudo +Open the file described on the current line, with root permissions +(@code{tramp-dired-find-file-with-sudo}). Calling it with the @kbd{C-u} +prefix argument asks for another Tramp method interactively but +@option{sudo}. @xref{Ad-hoc multi-hops, Tramp,, tramp, The Tramp Manual}. + @item ^ @kindex ^ @r{(Dired)} @findex dired-up-directory diff --git a/doc/emacs/files.texi b/doc/emacs/files.texi index d11d7767353..9b2ce5c5ee2 100644 --- a/doc/emacs/files.texi +++ b/doc/emacs/files.texi @@ -1174,6 +1174,15 @@ the major mode actually turned on as result of reverting a buffer depends on mode remapping, and could be different from the original mode if you customized @code{major-mode-remap-alist} in-between. +@cindex reverting with root permissions +@findex tramp-revert-buffer-with-sudo +@kindex C-x x @@ +A variant of reverting a buffer is visiting it by the +@code{tramp-revert-buffer-with-sudo} (@kbd{C-x x @@}) command. It +reopens the file or Dired buffer with root permissions. With a prefix +argument of @kbd{C-u}, you could change the default Tramp method +(@option{sudo}). @xref{Ad-hoc multi-hops, Tramp,, tramp, The Tramp Manual}. + @node Auto Revert @section Auto Revert: Keeping buffers automatically up-to-date @cindex Global Auto Revert mode diff --git a/doc/misc/tramp.texi b/doc/misc/tramp.texi index 81feb56ec31..6e66de552de 100644 --- a/doc/misc/tramp.texi +++ b/doc/misc/tramp.texi @@ -3928,23 +3928,31 @@ containers on the remote host. 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. +method. The commands @code{tramp-revert-buffer-with-sudo} (@kbd{C-x x +@@}), and @code{tramp-dired-find-file-with-sudo} (@kbd{@@} in +@code{dired-mode}) support this. +@kindex C-x x @@ @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 @option{sudo}, other valid methods are -@option{su}, @option{doas}, @option{run0}, and @option{ksu}. +@kindex @@ @r{(in dired}) +@deffn Command tramp-dired-find-file-with-sudo +In @code{dired-mode}, visit the file or directory named on this line. +This is performed with @option{sudo} permissions. +@end deffn -@lisp -(customize-set-variable 'tramp-file-name-with-method "doas") -@end lisp +@defopt tramp-file-name-with-method +The method used in @code{tramp-revert-buffer-with-sudo} and +@code{tramp-dired-find-file-with-sudo}. It defaults to @option{sudo}, +other valid methods are @option{su}, @option{doas}, @option{run0}, and +@option{ksu}. + +If a command is called with a prefix argument @kbd{C-u}, the option's +value is read interactively. @end defopt These methods apply the user @samp{root} as default. If another user diff --git a/etc/NEWS b/etc/NEWS index 5ebc109f734..e634de18c69 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -285,7 +285,6 @@ return value windows whose buffers share their text with BUFFER-OR-NAME. With such an entry, 'display-buffer-reuse-window' may also choose a window whose buffer shares text with the buffer to display. - ** Frames +++ @@ -294,7 +293,7 @@ Calling this function before 'delete-frame' is useful to avoid that the latter throws an error when the argument FRAME cannot be deleted. +++ -*** New value 'force' for option `frame-inhibit-implied-resize'. +*** New value 'force' for user option 'frame-inhibit-implied-resize'. This will inhibit implied resizing while a new frame is made and can be useful on tiling window managers where the initial frame size should be specified by external means. @@ -363,8 +362,6 @@ invoked standalone or from the 'project-switch-commands' dispatch menu. This user option describes projects that should always be skipped by 'project-remember-project'. -*** - ** Registers *** New functions 'buffer-to-register' and 'file-to-register'. @@ -396,14 +393,14 @@ please contact us if you still need it for some reason. --- ** Modified settings for an enabled theme now apply immediately. -Evaluating a custom-theme-set-faces or custom-theme-set-variables +Evaluating a 'custom-theme-set-faces' or 'custom-theme-set-variables' call for an enabled theme causes the settings to apply immediately, without a need to re-load the theme. --- ** 'describe-variable' now automatically says if 'setopt' is needed. -If a user option has a defcustom :set function, users will normally need -to set it with 'setopt' for it to take an effect. If the docstring +If a user option has a defcustom ':set' function, users will normally +need to set it with 'setopt' for it to take an effect. If the docstring doesn't already mention 'setopt', the 'describe-variable' command will now add a note about this automatically. @@ -545,6 +542,7 @@ default is nil, which retains the old format. *** The terminal emulator now supports auto-margins control. Term mode now handles DECAWM escape sequences that control whether text automatically wraps at the right margin: + - \e[?7h enables auto-margins (default) - \e[?7l disables auto-margins @@ -603,12 +601,13 @@ Emacs 25.1), and gnudoit (obsolete since Emacs 25.1). *** Some cl-lib functions and macros are now built-in. These functions or macros have been added to Emacs Lisp, and the old names are now aliases for the built-in equivalents: - - 'cl-incf' renamed to 'incf' - - 'cl-decf' renamed to 'decf' - - 'cl-oddp' renamed to 'oddp' - - 'cl-evenp' renamed to 'evenp' - - 'cl-plusp' renamed to 'plusp' - - 'cl-minusp' renamed to 'minusp' + +- 'cl-incf' renamed to 'incf' +- 'cl-decf' renamed to 'decf' +- 'cl-oddp' renamed to 'oddp' +- 'cl-evenp' renamed to 'evenp' +- 'cl-plusp' renamed to 'plusp' +- 'cl-minusp' renamed to 'minusp' The old names are considered deprecated, and will be marked as obsolete in some future release. @@ -687,6 +686,7 @@ minibuffer use, they are now saved only once in the file specified by 'savehist-file'. Previously, they were saved twice. ** Rectangle Mark + --- *** New user option to control whether empty rectangle selections are shown. The new user option 'rectangle-indicate-zero-width-rectangle' can be @@ -740,9 +740,8 @@ It removes all the buttons in the specified region. ** Shell ---- ++++ *** Shell buffers now support bookmarks. - You can now bookmark local and remote shell buffers using the bookmark menu 'bookmark-bmenu-list', or by using the command 'bookmark-set'. Shell bookmarks can be loaded via the menu and by using the command @@ -1021,7 +1020,7 @@ positives. --- *** IELM input history is now saved also when the IELM process is killed. -When you kill the IELM process with "C-c C-c", the input history is now +When you kill the IELM process with 'C-c C-c', the input history is now saved to the file specified by 'ielm-history-file-name', just like when you exit the Emacs session or kill the IELM buffer. @@ -1076,6 +1075,16 @@ connections after you close remote-file buffers without having to either cherry pick via 'tramp-cleanup-connection' or clear them all via 'tramp-cleanup-all-connections'. ++++ +*** New command 'tramp-dired-find-file-with-sudo'. +This command, bound to '@' in Dired, visits the file or directory on the +recent Dired line with root permissions. + ++++ +*** Command 'tramp-revert-buffer-with-sudo' is bound to 'C-x x @' now. +Called with the prefix argument 'C-u', the used Tramp method is asked +interactively. This happens also for 'tramp-dired-find-file-with-sudo'. + +++ *** Connection method "kubernetes" supports now optional namespace. The host name for Kubernetes connections can be of kind @@ -1371,19 +1380,19 @@ the directory into which the repository was cloned. *** 'C-x v u' ('vc-revert') now works on directories listed in VC Directory. Reverting a directory means reverting changes to all files inside it. -*** New function 'log-edit-done-strip-cvs-lines'. -This function strips all lines beginning with "CVS:" from the buffer. +*** New command 'log-edit-done-strip-cvs-lines'. +This command strips all lines beginning with "CVS:" from the buffer. It is intended to be added to the 'log-edit-done-hook' so that -'vc-cvs-checkin' behaves like invoking "cvs commit [files...]" from the +'vc-cvs-checkin' behaves like invoking 'cvs commit [files...]' from the command line. ** Diff mode +++ -*** diff-apply-buffer now considers the region and can reverse-apply. +*** 'diff-apply-buffer' now considers the region and can reverse-apply. If the region is active, this command now applies all hunks that the region overlaps; otherwise, it applies all hunks. -With a prefix arguments, it now reverse-applies the hunks. +With a prefix argument, it now reverse-applies the hunks. This matches the existing prefix argument to 'diff-apply-hunk'. ** Package @@ -1448,13 +1457,13 @@ runs its body, and removes the current buffer from ** Strokes -- -** 'strokes-mode' no longer demands the presence of a mouse. +*** 'strokes-mode' no longer demands the presence of a mouse. 'strokes-mode' now permits itself to be enabled if no mouse is connected, to facilitate enabling 'strokes-mode' in sessions where the availability of a mouse device varies during execution (as is frequently observed on Android). -** Yank media +** Yank Media +++ *** 'yank-media' now auto-selects the most preferred MIME type. @@ -1472,7 +1481,7 @@ the 'remember-buffer'. This allows users to customize the major mode used to write notes. --- -*** New handler that append remember data in directory. +*** New handler that appends remember data in directory. The 'remember-append-in-data-directory' handler appends remember data in a file, that file being choosen by the user through the minibuffer. @@ -1593,28 +1602,28 @@ restore the old behavior, you can set 'eshell-pwd-convert-function' to 'identity'. --- -** The rx 'eval' form now uses the current elisp dialect for evaluation. +** The rx 'eval' form now uses the current Elisp dialect for evaluation. Previously, its argument was always evaluated using dynamic binding. * Lisp Changes in Emacs 31.1 +++ -** New macros 'static-when' and 'static-unless' implement conditional -compilation like 'static-if'. -These macros evaluate their condition at macro-expansion time and are useful -for writing code that can work across different Emacs versions. +** New macros 'static-when' and 'static-unless'. +Like 'static-if', these macros evaluate their condition at +macro-expansion time and are useful for writing code that can work +across different Emacs versions. --- ** You can change the default value of 'lexical-binding'. -While the default is still the use dynamic binding dialect of Elisp +While the default is still the use of dynamic binding dialect of Elisp in those places that don't explicitly set 'lexical-binding' you can change it globally with: (set-default-toplevel-value 'lexical-binding t) +++ -*** New macros 'incf' and 'decf'. +** New macros 'incf' and 'decf'. They increment or decrement the value stored in a variable (a symbol), or in a generalized variable. @@ -1638,11 +1647,12 @@ This means that you can now call it with just one argument, like *** Some experimental ERT macros are now considered stable. The following macros, previously only available in the experimental 'ert-x' module, are now considered stable and have been moved to 'ert': + - ert-with-test-buffer - ert-with-buffer-selected - ert-with-buffer-renamed -See the ERT manual for more information. +See "(ert) Helper Functions" node in the ERT manual for more information. ** Time & Date @@ -1852,7 +1862,7 @@ maps will not activate the repeat map in 'repeat-mode'. It will only continue the already activated repeating sequence. Also 'defvar-keymap' supports a new keyword ':continue' with a list of commands that only continue the active repeating sequence, and the 'use-package' and -'bind-keys' macros supports a similar keyword ':continue-only'. +'bind-keys' macros support a similar keyword ':continue-only'. ** New function 'completion-table-with-metadata'. It offers a more concise way to create a completion table with metadata. diff --git a/lisp/bindings.el b/lisp/bindings.el index f829c1bea26..a5737db840b 100644 --- a/lisp/bindings.el +++ b/lisp/bindings.el @@ -1606,7 +1606,8 @@ if `inhibit-field-text-motion' is non-nil." "u" #'rename-uniquely "n" #'clone-buffer "i" #'insert-buffer - "t" #'toggle-truncate-lines) + "t" #'toggle-truncate-lines + "@" #'tramp-revert-buffer-with-sudo) (define-key ctl-x-map "x" ctl-x-x-map) (define-key esc-map "\C-l" 'reposition-window) diff --git a/lisp/dired.el b/lisp/dired.el index 68e1da13171..b5bb658b503 100644 --- a/lisp/dired.el +++ b/lisp/dired.el @@ -2416,6 +2416,7 @@ Do so according to the former subdir alist OLD-SUBDIR-ALIST." "x" #'dired-do-flagged-delete "y" #'dired-show-file-type "+" #'dired-create-directory + "@" #'tramp-dired-find-file-with-sudo ;; moving "<" #'dired-prev-dirline ">" #'dired-next-dirline diff --git a/lisp/net/tramp-cmds.el b/lisp/net/tramp-cmds.el index cba300049ae..be122642b96 100644 --- a/lisp/net/tramp-cmds.el +++ b/lisp/net/tramp-cmds.el @@ -32,6 +32,7 @@ ;; Pacify byte-compiler. (declare-function dired-advertise "dired") +(declare-function dired-get-file-for-visit "dired") (declare-function dired-unadvertise "dired") (declare-function mml-mode "mml") (declare-function mml-insert-empty-tag "mml") @@ -637,6 +638,19 @@ For details, see `tramp-rename-files'." (const "ksu")) :link '(tramp-info-link :tag "Tramp manual" tramp-file-name-with-method)) +(defmacro with-tramp-file-name-with-method (&rest body) + "Ask user for `tramp-file-name-with-method' if needed. +Run BODY." + (declare (indent 0) (debug t)) + `(let ((tramp-file-name-with-method + (if current-prefix-arg + (completing-read + "Tramp method: " + (mapcar #'cadr (cdr (get 'tramp-file-name-with-method 'custom-type))) + nil t tramp-file-name-with-method) + tramp-file-name-with-method))) + ,@body)) + (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'." @@ -669,27 +683,38 @@ An alternative method could be chosen with `tramp-file-name-with-method'." (make-tramp-file-name :method tramp-file-name-with-method :localname filename)))) -;;;###tramp-autoload +;;;###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-file-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)))) + (with-tramp-file-name-with-method + (cond + ((buffer-file-name) + (let ((pos (point))) + (find-alternate-file (tramp-file-name-with-sudo (buffer-file-name))) + (goto-char pos))) + ((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))))) + +;;;###autoload +(defun tramp-dired-find-file-with-sudo () + "In Dired, visit the file or directory named on this line. +This is performed with \"sudo\" permissions." + (interactive) + (with-tramp-file-name-with-method + (find-file (tramp-file-name-with-sudo (dired-get-file-for-visit))))) ;;; Recompile on ELPA