+;; Pacify the byte-compiler.
+(defvar tramp-default-proxies-alist)
+
+(defun eshell/su (&rest args)
+ "Alias \"su\" to call Tramp."
+ (require 'tramp)
+ (setq args (eshell-stringify-list (eshell-flatten-list args)))
+ (let ((orig-args (copy-tree args)))
+ (eshell-eval-using-options
+ "su" args
+ '((?h "help" nil nil "show this usage screen")
+ (?l "login" nil login "provide a login environment")
+ (? nil nil login "provide a login environment")
+ :usage "[- | -l | --login] [USER]
+Become another USER during a login session.")
+ (throw 'eshell-replace-command
+ (let ((user "root")
+ (host (or (file-remote-p default-directory 'host)
+ "localhost"))
+ (dir (or (file-remote-p default-directory 'localname)
+ (expand-file-name default-directory))))
+ (dolist (arg args)
+ (if (string-equal arg "-") (setq login t) (setq user arg)))
+ ;; `eshell-eval-using-options' does not handle "-".
+ (if (member "-" orig-args) (setq login t))
+ (if login (setq dir "~/"))
+ (if (and (file-remote-p default-directory)
+ (or
+ (not (string-equal
+ "su" (file-remote-p default-directory 'method)))
+ (not (string-equal
+ user (file-remote-p default-directory 'user)))))
+ (add-to-list
+ 'tramp-default-proxies-alist
+ (list host user (file-remote-p default-directory))))
+ (eshell-parse-command
+ "cd" (list (format "/su:%s@%s:%s" user host dir))))))))
+
+(put 'eshell/su 'eshell-no-numeric-conversions t)
+
+(defun eshell/sudo (&rest args)
+ "Alias \"sudo\" to call Tramp."
+ (require 'tramp)
+ (setq args (eshell-stringify-list (eshell-flatten-list args)))
+ (let ((orig-args (copy-tree args)))
+ (eshell-eval-using-options
+ "sudo" args
+ '((?h "help" nil nil "show this usage screen")
+ (?u "user" t user "execute a command as another USER")
+ :show-usage
+ :usage "[(-u | --user) USER] COMMAND
+Execute a COMMAND as the superuser or another USER.")
+ (throw 'eshell-external
+ (let ((user (or user "root"))
+ (host (or (file-remote-p default-directory 'host)
+ "localhost"))
+ (dir (or (file-remote-p default-directory 'localname)
+ (expand-file-name default-directory))))
+ ;; `eshell-eval-using-options' reads options of COMMAND.
+ (while (and (stringp (car orig-args))
+ (member (car orig-args) '("-u" "--user")))
+ (setq orig-args (cddr orig-args)))
+ (if (and (file-remote-p default-directory)
+ (or
+ (not (string-equal
+ "sudo" (file-remote-p default-directory 'method)))
+ (not (string-equal
+ user (file-remote-p default-directory 'user)))))
+ (add-to-list
+ 'tramp-default-proxies-alist
+ (list host user (file-remote-p default-directory))))
+ (let ((default-directory (format "/sudo:%s@%s:%s" user host dir)))
+ (eshell-named-command (car orig-args) (cdr orig-args))))))))
+
+(put 'eshell/sudo 'eshell-no-numeric-conversions t)
+