From f18603e66a1160927044d13a46f15bbddfd72d39 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Fri, 5 Apr 2024 18:07:45 -0400 Subject: [PATCH] feat(lib): sudo-{find,this}-file: invoke save-place After switching to the sudo-ed tramp buffer, this restores the point and scroll position of the window to match the source buffer. I exploit save-place here instead of simply saving/restoring (point) and (window-start), because I believe it's better UX that save-place treat the two buffers as effectively the same now and in the future, and record the last cursor position equally between them, even if the implementation is messier. This *could* be generalized into an advice for save-place-find-file-hook and save-place-to-alist, but that's an experiment for another day. This is an experimental implementation and may change later. Close: #7181 Co-authored-by: YourFin --- lisp/lib/files.el | 55 +++++++++++++++++++++++++++++++++++++---------- 1 file changed, 44 insertions(+), 11 deletions(-) diff --git a/lisp/lib/files.el b/lisp/lib/files.el index 8f03b4abe..8550ec344 100644 --- a/lisp/lib/files.el +++ b/lisp/lib/files.el @@ -484,17 +484,50 @@ If FORCE-P, overwrite the destination file if it exists, without confirmation." file)))) ;;;###autoload -(defun doom/sudo-find-file (file) - "Open FILE as root." - (interactive "FOpen file as root: ") - ;; HACK: Disable auto-save in temporary tramp buffers because it could trigger - ;; processes that hang silently in the background, making those buffers - ;; inoperable for the rest of that session (Tramp caches them). - (let ((auto-save-default nil) - ;; REVIEW: use only these when we drop 28 support - (remote-file-name-inhibit-auto-save t) - (remote-file-name-inhibit-auto-save-visited t)) - (find-file (doom--sudo-file-path (expand-file-name file))))) +(defun doom/sudo-find-file (file &optional arg) + "Open FILE as root. + +This will prompt you to save the current buffer, unless prefix ARG is given, in +which case it will save it without prompting." + (interactive + (list (read-file-name "Open file as root: ") + current-prefix-arg)) + ;; HACK: Teach `save-place' to treat the new "remote" buffer as if it were + ;; visiting the same local file (because it is), and preserve the cursor + ;; position as usual. + (letf! ((defun remote-local-name (path) + (if path (or (file-remote-p path 'localname) path))) + (defmacro with-local-name (&rest body) + `(when save-place-mode + (let ((buffer-file-name (remote-local-name buffer-file-name)) + (default-directory (remote-local-name default-directory))) + ,@body)))) + (let ((window-start (window-start)) + (buffer (current-buffer))) + (when (and buffer-file-name (file-equal-p buffer-file-name file)) + (when (buffer-modified-p) + (save-some-buffers arg (lambda () (eq (current-buffer) buffer)))) + (with-local-name (save-place-to-alist))) + (prog1 + ;; HACK: Disable auto-save in temporary tramp buffers because it could + ;; trigger processes that hang silently in the background, making + ;; those buffers inoperable for the rest of that session (Tramp + ;; caches them). + (let ((auto-save-default nil) + ;; REVIEW: use only these when we drop 28 support + (remote-file-name-inhibit-auto-save t) + (remote-file-name-inhibit-auto-save-visited t) + ;; Prevent redundant work + save-place-mode) + (find-file (doom--sudo-file-path (expand-file-name file)))) + ;; Record of the cursor's old position if it isn't at BOB (indicating + ;; this buffer was already open), in case the user wishes to go to it. + (unless (bobp) + (doom-set-jump-h) + ;; save-place-find-file-hook requires point be a BOB to do its thang. + (goto-char (point-min))) + (with-local-name (save-place-find-file-hook)) + (set-window-start nil window-start))))) ;;;###autoload (defun doom/sudo-this-file ()