branch: externals/ssh-deploy commit 099c7d85f6c5cef5a601835283aecaa30f33883b Author: Christian Johansson <christ...@cvj.se> Commit: Christian Johansson <christ...@cvj.se>
Added support for mode-line status updates --- README.md | 1 + ssh-deploy.el | 325 +++++++++++++++++++++++++++++++++++++++++----------------- 2 files changed, 230 insertions(+), 96 deletions(-) diff --git a/README.md b/README.md index 49c6893..607995c 100644 --- a/README.md +++ b/README.md @@ -38,6 +38,7 @@ Here is a list of other variables you can set globally or per directory: * `ssh-deploy-remote-sql-port` - Default port when connecting to remote SQL database *(integer)* * `ssh-deploy-remote-sql-server` Default server when connecting to remote SQL database *(string)* * `ssh-deploy-remote-sql-user` Default user when connecting to remote SQL database *(string)* +* `ssh-deploy-remote-shell-executable` Default remote shell executable when launching shell on remote host *(string)* ## Deployment configuration examples diff --git a/ssh-deploy.el b/ssh-deploy.el index b3d6c30..714fb43 100644 --- a/ssh-deploy.el +++ b/ssh-deploy.el @@ -3,8 +3,8 @@ ;; Author: Christian Johansson <github.com/cjohansson> ;; Maintainer: Christian Johansson <github.com/cjohansson> ;; Created: 5 Jul 2016 -;; Modified: 28 Jun 2018 -;; Version: 1.9 +;; Modified: 3 July 2018 +;; Version: 1.91 ;; Keywords: tools, convenience ;; URL: https://github.com/cjohansson/emacs-ssh-deploy @@ -151,16 +151,14 @@ ;; * `ssh-deploy-remote-sql-port' - Default port when connecting to remote SQL database *(integer)* ;; * `ssh-deploy-remote-sql-server' - Default server when connecting to remote SQL database *(string)* ;; * `ssh-deploy-remote-sql-user' - Default user when connecting to remote SQL database *(string)* +;; * `ssh-deploy-remote-shell-executable' - Default shell executable when launching shell on remote host ;; ;; Please see README.md from the same repository for extended documentation. ;;; Code: -;; TODO Rename function does not work properly sometimes? -;; TODO Downloading/uploading file asynchronously from diff-mode sometimes outputs tramp in messages, investigate this, it should show any tramp output? - -(require 'ssh-deploy-diff-mode) ;; FIXME flycheck complains, why? +(require 'ssh-deploy-diff-mode) ;; FIXME flycheck complains.. but why? (defgroup ssh-deploy nil "Upload, download, difference, browse and terminal handler for files and directories on remote hosts via TRAMP." @@ -258,6 +256,37 @@ (put 'ssh-deploy-remote-sql-user 'permanent-local t) (put 'ssh-deploy-remote-sql-user 'safe-local-variable 'stringp) +(defcustom ssh-deploy-remote-shell-executable nil + "String variable of remote shell executable server, nil by default." + :type 'string + :group 'ssh-deploy) +(put 'ssh-deploy-remote-shell-executable 'permanent-local t) +(put 'ssh-deploy-remote-shell-executable 'safe-local-variable 'stringp) + +(defconst ssh-deploy--status-idle 0 + "The idle mode-line status.") + +(defconst ssh-deploy--status-downloading 1 + "The downloading mode-line status.") + +(defconst ssh-deploy--status-uploading 2 + "The uploading mode-line status.") + +(defconst ssh-deploy--status-deleting 3 + "The deleting mode-line status.") + +(defconst ssh-deploy--status-renaming 4 + "The renaming mode-line status.") + +(defconst ssh-deploy--status-detecting-remote-changes 5 + "The mode-line status for detecting remote changes.") + +(defvar ssh-deploy--mode-line-status 0 + "The mode-line status displayed in mode-line.") + +(defvar ssh-deploy--mode-line-status-text "" + "The mode-line status text displayed in mode-line.") + ;; PRIVATE FUNCTIONS ;; @@ -265,6 +294,62 @@ ;; these functions MUST not use module variables. +(defun ssh-deploy--mode-line-set-status-and-update (status &optional filename) + "Set the mode line STATUS in optionally in buffer visiting FILENAME." + (if (and (boundp 'filename) + filename) + (save-excursion + (let ((buffer (find-buffer-visiting filename))) + (switch-to-buffer buffer) + (setq ssh-deploy--mode-line-status status) + (message "SSH Deploy - Updated status to %s" ssh-deploy--mode-line-status) + (ssh-deploy--mode-line-status-refresh))) + (progn + (setq ssh-deploy--mode-line-status status) + (message "SSH Deploy - Updated status to %s" ssh-deploy--mode-line-status) + (ssh-deploy--mode-line-status-refresh)))) + + +(defun ssh-deploy--mode-line-status-refresh () + "Refresh the status text based on the status variable." + (ssh-deploy--mode-line-status-update ssh-deploy--mode-line-status)) + +(defun ssh-deploy--mode-line-status-update (status) + "Update the local status text variable to a text representation based on STATUS." + (let ((status-text "")) + (cond + + ((= status ssh-deploy--status-idle) + (setq status-text "idle")) + + ((= status ssh-deploy--status-downloading) + (setq status-text "dl..")) + + ((= status ssh-deploy--status-uploading) + (setq status-text "ul..")) + + ((= status ssh-deploy--status-deleting) + (setq status-text "..")) + + ((= status ssh-deploy--status-renaming) + (setq status-text "mv..")) + + ((= status ssh-deploy--status-detecting-remote-changes) + (setq status-text "diff..")) + + (t (setq status-text "?")) + + ) + (make-local-variable 'ssh-deploy--mode-line-status-text) + (setq ssh-deploy--mode-line-status-text (ssh-deploy--mode-line-status-text-format status-text)) + (message "SSH Deploy - Updated status text to %s" ssh-deploy--mode-line-status-text))) + +(defun ssh-deploy--mode-line-status-text-format (text) + "Return a formatted string based on TEXT." + (if (string= text "") + (format " SH ") + (format " SH:%s " text))) + (defun ssh-deploy--insert-keyword (text) "Insert TEXT as bold text." (put-text-property 0 (length text) 'face 'font-lock-keyword-face text) @@ -302,6 +387,7 @@ "Upload PATH-LOCAL to PATH-REMOTE via TRAMP asynchronously and FORCE upload despite remote change, check for revisions in REVISION-FOLDER." (if (fboundp 'async-start) (let ((file-or-directory (not (file-directory-p path-local)))) + (ssh-deploy--mode-line-set-status-and-update ssh-deploy--status-uploading) (if file-or-directory (let ((revision-path (ssh-deploy--get-revision-path path-local revision-folder))) (message "Uploading file '%s' to '%s'.. (asynchronously)" path-local path-remote) @@ -315,10 +401,11 @@ (make-directory (file-name-directory ,path-remote) t)) (copy-file ,path-local ,path-remote t t t t) (copy-file ,path-local ,revision-path t t t t) - (list 0 (format "Completed upload of file '%s'. (asynchronously)" ,path-remote))) - (list 1 (format "Remote file '%s' has changed, please download or diff. (asynchronously)" ,path-remote))) - (list 1 "Function 'ediff-same-file-contents' is missing. (asynchronously)"))) + (list 0 (format "Completed upload of file '%s'. (asynchronously)" ,path-remote) ,path-local)) + (list 1 (format "Remote file '%s' has changed, please download or diff. (asynchronously)" ,path-remote) ,path-local)) + (list 1 "Function 'ediff-same-file-contents' is missing. (asynchronously)" ,path-local))) (lambda(return) + (ssh-deploy--mode-line-set-status-and-update ssh-deploy--status-idle (nth 2 return)) (if (= (nth 0 return) 0) (message (nth 1 return)) (display-warning 'ssh-deploy (nth 1 return) :warning))))) @@ -329,6 +416,7 @@ (copy-directory ,path-local ,path-remote t t t) ,path-local) (lambda(return-path) + (ssh-deploy--mode-line-set-status-and-update ssh-deploy--status-idle return-path) (message "Completed upload of directory '%s'. (asynchronously)" return-path)))))) (message "async.el is not installed"))) @@ -336,6 +424,7 @@ "Upload PATH-LOCAL to PATH-REMOTE via TRAMP synchronously and FORCE despite remote change compared with copy in REVISION-FOLDER." (let ((file-or-directory (not (file-directory-p path-local))) (revision-path (ssh-deploy--get-revision-path path-local revision-folder))) + (ssh-deploy--mode-line-set-status-and-update ssh-deploy--status-uploading) (if file-or-directory (progn (require 'ediff-util) @@ -351,16 +440,19 @@ (ssh-deploy-store-revision path-local revision-folder) (message "Completed upload of '%s'. (synchronously)" path-local)) (display-warning 'ssh-deploy (format "Remote file '%s' has changed, please download or diff. (synchronously)" path-remote) :warning)) - (display-warning 'ssh-deploy "Function 'ediff-same-file-contents' is missing." :warning))) + (display-warning 'ssh-deploy "Function 'ediff-same-file-contents' is missing." :warning)) + (ssh-deploy--mode-line-set-status-and-update ssh-deploy--status-idle)) (progn (message "Uploading directory '%s' to '%s'.. (synchronously)" path-local path-remote) (copy-directory path-local path-remote t t t) + (ssh-deploy--mode-line-set-status-and-update ssh-deploy--status-idle) (message "Completed upload of '%s'. (synchronously)" path-local))))) (defun ssh-deploy--download-via-tramp-async (path-remote path-local revision-folder) "Download PATH-REMOTE to PATH-LOCAL via TRAMP asynchronously and make a copy in REVISION-FOLDER." (if (fboundp 'async-start) (let ((revision-path (ssh-deploy--get-revision-path path-local revision-folder))) + (ssh-deploy--mode-line-set-status-and-update ssh-deploy--status-downloading) (message "Downloading '%s' to '%s'.. (asynchronously)" path-remote path-local) (async-start `(lambda() @@ -374,12 +466,14 @@ (copy-directory ,path-remote ,path-local t t t)) ,path-local)) (lambda(return-path) + (ssh-deploy--mode-line-set-status-and-update ssh-deploy--status-idle return-path) (message "Completed download of '%s'. (asynchronously)" return-path)))) (display-warning 'ssh-deploy "async.el is not installed" :warning))) (defun ssh-deploy--download-via-tramp (path-remote path-local revision-folder) "Download PATH-REMOTE to PATH-LOCAL via TRAMP synchronously and store a copy in REVISION-FOLDER." (let ((file-or-directory (not (file-directory-p path-remote)))) + (ssh-deploy--mode-line-set-status-and-update ssh-deploy--status-downloading) (if file-or-directory (progn (message "Downloading file '%s' to '%s'.. (synchronously)" path-remote path-local) @@ -387,10 +481,12 @@ (make-directory (file-name-directory path-local) t)) (copy-file path-remote path-local t t t t) (ssh-deploy-store-revision path-local revision-folder) + (ssh-deploy--mode-line-set-status-and-update ssh-deploy--status-idle) (message "Completed download of file '%s'. (synchronously)" path-local)) (progn (message "Downloading directory '%s' to '%s'.. (synchronously)" path-remote path-local) (copy-directory path-remote path-local t t t) + (ssh-deploy--mode-line-set-status-and-update ssh-deploy--status-idle) (message "Completed download of directory '%s'. (synchronously)" path-local))))) (defun ssh-deploy--diff-directories-data (directory-a directory-b exclude-list) @@ -621,88 +717,110 @@ (revision-path (ssh-deploy--get-revision-path path-local revision-folder)) (path-remote (concat root-remote (ssh-deploy--get-relative-path root-local path-local)))) (if (not (file-directory-p path-local)) - (if (file-exists-p revision-path) - (if (and async (fboundp 'async-start)) - (async-start - `(lambda() - (if (file-exists-p ,path-remote) - (progn - (require 'ediff-util) - (if (fboundp 'ediff-same-file-contents) - (if (ediff-same-file-contents ,revision-path ,path-remote) - (list 0 (format "Remote file '%s' has not changed. (asynchronously)" ,path-remote)) - (if (ediff-same-file-contents ,path-local ,path-remote) - (progn - (copy-file ,path-local ,revision-path t t t t) - (list 0 (format "Remote file '%s' is identical to local file '%s' but different to local revision. Updated local revision. (asynchronously)" ,path-remote ,path-local))) - (list 1 (format "Remote file '%s' has changed, please download or diff. (asynchronously)" ,path-remote)))) - (list 1 "Function 'ediff-same-file-contents' is missing. (asynchronously)"))) - (list 0 (format "Remote file '%s' doesn't exist. (asynchronously)" ,path-remote)))) - (lambda(return) - (if (= (nth 0 return) 0) - (message (nth 1 return)) - (display-warning 'ssh-deploy (nth 1 return) :warning)))) - (if (file-exists-p path-remote) - (progn - (require 'ediff-util) - (if (fboundp 'ediff-same-file-contents) - (if (ediff-same-file-contents revision-path path-remote) - (message "Remote file '%s' has not changed. (synchronously)" path-remote) - (display-warning 'ssh-deploy (format "Remote file '%s' has changed, please download or diff. (synchronously)" path-remote) :warning)) - (display-warning 'ssh-deploy "Function 'ediff-same-file-contents' is missing. (synchronously)" :warning))) - (message "Remote file '%s' doesn't exist. (synchronously)" path-remote))) - (if (and async (fboundp 'async-start)) - (async-start - `(lambda() - (if (file-exists-p ,path-remote) + (progn + (ssh-deploy--mode-line-set-status-and-update ssh-deploy--status-detecting-remote-changes) + (if (file-exists-p revision-path) + (if (and async (fboundp 'async-start)) + (async-start + `(lambda() + (if (file-exists-p ,path-remote) + (progn + (require 'ediff-util) + (if (fboundp 'ediff-same-file-contents) + (if (ediff-same-file-contents ,revision-path ,path-remote) + (list 0 (format "Remote file '%s' has not changed. (asynchronously)" ,path-remote) ,path-local) + (if (ediff-same-file-contents ,path-local ,path-remote) + (progn + (copy-file ,path-local ,revision-path t t t t) + (list 0 (format "Remote file '%s' is identical to local file '%s' but different to local revision. Updated local revision. (asynchronously)" ,path-remote ,path-local) ,path-local)) + (list 1 (format "Remote file '%s' has changed, please download or diff. (asynchronously)" ,path-remote) ,path-local))) + (list 1 "Function 'ediff-same-file-contents' is missing. (asynchronously)" ,path-local))) + (list 0 (format "Remote file '%s' doesn't exist. (asynchronously)" ,path-remote) ,path-local))) + (lambda(return) + (ssh-deploy--mode-line-set-status-and-update ssh-deploy--status-idle (nth 2 return)) + (if (= (nth 0 return) 0) + (message (nth 1 return)) + (display-warning 'ssh-deploy (nth 1 return) :warning)))) + (progn + (if (file-exists-p path-remote) (progn (require 'ediff-util) (if (fboundp 'ediff-same-file-contents) - (if (ediff-same-file-contents ,path-local ,path-remote) - (progn - (copy-file ,path-local ,revision-path t t t t) - (list 0 (format "Remote file '%s' has not changed, created base revision. (asynchronously)" ,path-remote))) - (list 1 (format "Remote file '%s' has changed, please download or diff. (asynchronously)" ,path-remote))) - (list 1 "Function ediff-file-same-contents is missing. (asynchronously)"))) - (list 0 (format "Remote file '%s' doesn't exist. (asynchronously)" ,path-remote)))) - (lambda(return) - (if (= (nth 0 return) 0) - (message (nth 1 return)) - (display-warning 'ssh-deploy (nth 1 return) :warning)))) - (if (file-exists-p path-remote) - (progn - (require 'ediff-util) - (if (fboundp 'ediff-same-file-contents) - (if (ediff-same-file-contents path-local path-remote) - (progn - (copy-file path-local revision-path t t t t) - (message "Remote file '%s' has not changed, created base revision. (synchronously)" path-remote)) - (display-warning 'ssh-deploy (format "Remote file '%s' has changed, please download or diff. (synchronously)" path-remote) :warning)) - (display-warning 'ssh-deploy "Function 'ediff-same-file-contents' is missing. (synchronously)" :warning))) - (message "Remote file '%s' does not exist. (synchronously)" path-remote))))))))) - -(defun ssh-deploy-delete (path &optional async debug) - "Delete PATH and use flags ASYNC and DEBUG." + (if (ediff-same-file-contents revision-path path-remote) + (message "Remote file '%s' has not changed. (synchronously)" path-remote) + (display-warning 'ssh-deploy (format "Remote file '%s' has changed, please download or diff. (synchronously)" path-remote) :warning)) + (display-warning 'ssh-deploy "Function 'ediff-same-file-contents' is missing. (synchronously)" :warning))) + (message "Remote file '%s' doesn't exist. (synchronously)" path-remote)) + (ssh-deploy--mode-line-set-status-and-update ssh-deploy--status-idle)) + (if (and async (fboundp 'async-start)) + (async-start + `(lambda() + (if (file-exists-p ,path-remote) + (progn + (require 'ediff-util) + (if (fboundp 'ediff-same-file-contents) + (if (ediff-same-file-contents ,path-local ,path-remote) + (progn + (copy-file ,path-local ,revision-path t t t t) + (list 0 (format "Remote file '%s' has not changed, created base revision. (asynchronously)" ,path-remote) ,path-local)) + (list 1 (format "Remote file '%s' has changed, please download or diff. (asynchronously)" ,path-remote) ,path-local)) + (list 1 "Function ediff-file-same-contents is missing. (asynchronously)" ,path-local))) + (list 0 (format "Remote file '%s' doesn't exist. (asynchronously)" ,path-remote) ,path-local))) + (lambda(return) + (ssh-deploy--mode-line-set-status-and-update ssh-deploy--status-idle (nth 2 return)) + (if (= (nth 0 return) 0) + (message (nth 1 return)) + (display-warning 'ssh-deploy (nth 1 return) :warning)))) + (progn + (if (file-exists-p path-remote) + (progn + (require 'ediff-util) + (if (fboundp 'ediff-same-file-contents) + (if (ediff-same-file-contents path-local path-remote) + (progn + (copy-file path-local revision-path t t t t) + (message "Remote file '%s' has not changed, created base revision. (synchronously)" path-remote)) + (display-warning 'ssh-deploy (format "Remote file '%s' has changed, please download or diff. (synchronously)" path-remote) :warning)) + (display-warning 'ssh-deploy "Function 'ediff-same-file-contents' is missing. (synchronously)" :warning))) + (message "Remote file '%s' does not exist. (synchronously)" path-remote)) + (ssh-deploy--mode-line-set-status-and-update ssh-deploy--status-idle)))) + (ssh-deploy--mode-line-set-status-and-update ssh-deploy--status-idle)))))))) + +(defun ssh-deploy-delete (path &optional async debug buffer) + "Delete PATH and use flags ASYNC and DEBUG, set status in BUFFER." (if (and async (fboundp 'async-start)) (async-start `(lambda() (if (file-exists-p ,path) - (let ((file-or-directory (not (file-directory-p ,path)))) - (progn - (if file-or-directory - (delete-file ,path t) - (delete-directory ,path t t)) - (list ,path 0))) - (list ,path 1))) + (when (and (boundp 'buffer) + buffer) + (ssh-deploy--mode-line-set-status-and-update ssh-deploy--status-deleting buffer)) + (let ((file-or-directory (not (file-directory-p ,path)))) + (progn + (if file-or-directory + (delete-file ,path t) + (delete-directory ,path t t)) + (list ,path 0 buffer))) + (list ,path 1 buffer))) (lambda(response) + (when (boundp (nth 2 response)) + (ssh-deploy--mode-line-set-status-and-update ssh-deploy--status-idle (nth 2 response)) + (kill-buffer (find-buffer-visiting (nth 2 response)))) (cond ((= 0 (nth 1 response)) (message "Completed deletion of '%s'. (asynchronously)" (nth 0 response))) (t (display-warning 'ssh-deploy (format "Did not find '%s' for deletion. (asynchronously)" (nth 0 response)) :warning))))) (if (file-exists-p path) (let ((file-or-directory (not (file-directory-p path)))) + (when (and (boundp 'buffer) + buffer) + (ssh-deploy--mode-line-set-status-and-update ssh-deploy--status-deleting buffer)) (progn (if file-or-directory (delete-file path t) (delete-directory path t t)) + (when (and (boundp 'buffer) + buffer) + (ssh-deploy--mode-line-set-status-and-update ssh-deploy--status-idle) + (kill-buffer (find-buffer-visiting buffer))) (message "Completed deletion of '%s'. (synchronously)" path))) (display-warning 'ssh-deploy (format "Did not find '%s' for deletion. (synchronously)" path) :warning)))) @@ -716,9 +834,8 @@ (let ((exclude-list (or exclude-list ssh-deploy-exclude-list)) (file-or-directory (not (file-directory-p path-local))) (path-remote (concat root-remote (ssh-deploy--get-relative-path root-local path-local)))) - (ssh-deploy-delete path-local async debug) - (kill-this-buffer) - (ssh-deploy-delete path-remote async debug)) + (ssh-deploy-delete path-local async debug path-local) + (ssh-deploy-delete path-remote async debug path-local)) (if debug (message "Path '%s' is not in the root '%s' or is excluded from it." path-local root-local))))) @@ -739,6 +856,7 @@ (file-or-directory (not (file-directory-p old-path-local))) (old-path-remote (concat root-remote (ssh-deploy--get-relative-path root-local old-path-local))) (new-path-remote (concat root-remote (ssh-deploy--get-relative-path root-local new-path-local)))) + (ssh-deploy--mode-line-set-status-and-update ssh-deploy--status-renaming) (rename-file old-path-local new-path-local t) (if (not (file-directory-p new-path-local)) (progn @@ -751,11 +869,13 @@ (async-start `(lambda() (rename-file ,old-path-remote ,new-path-remote t) - (list ,old-path-remote ,new-path-remote)) + (list ,old-path-remote ,new-path-remote ,new-path-local)) (lambda(files) + (ssh-deploy--mode-line-set-status-and-update ssh-deploy--status-idle (nth 2 files)) (message "Renamed '%s' to '%s'. (asynchronously)" (nth 0 files) (nth 1 files)))) (progn (rename-file old-path-remote new-path-remote t) + (ssh-deploy--mode-line-set-status-and-update ssh-deploy--status-idle) (message "Renamed '%s' to '%s'. (synchronously)" old-path-remote new-path-remote)))) (if debug (message "Path '%s' or '%s' is not in the root '%s' or is excluded from it." old-path-local new-path-local root-local))))) @@ -803,15 +923,15 @@ (root-local (or root-local ssh-deploy-root-local)) (root-remote (or root-remote ssh-deploy-root-remote))) (when (and (ssh-deploy--file-is-in-path path-local root-local) - (ssh-deploy--file-is-included path-local exclude-list)) - (let ((path-remote (concat root-remote (ssh-deploy--get-relative-path root-local path-local)))) - (let ((old-directory default-directory)) - (require 'eshell) - (message "Opening eshell on '%s'.." path-remote) - (let ((default-directory path-remote)) - (defvar eshell-buffer-name) - (setq eshell-buffer-name path-remote) - (eshell))))))) + (ssh-deploy--file-is-included path-local exclude-list)) + (let ((path-remote (concat root-remote (ssh-deploy--get-relative-path root-local path-local)))) + (let ((old-directory default-directory)) + (require 'eshell) + (message "Opening eshell on '%s'.." path-remote) + (let ((default-directory path-remote)) + (defvar eshell-buffer-name) + (setq eshell-buffer-name path-remote) + (eshell))))))) ;;;### autoload (defun ssh-deploy-remote-terminal-shell (path-local &optional root-local root-remote exclude-list) @@ -820,13 +940,14 @@ (root-local (or root-local ssh-deploy-root-local)) (root-remote (or root-remote ssh-deploy-root-remote))) (when (and (ssh-deploy--file-is-in-path path-local root-local) - (ssh-deploy--file-is-included path-local exclude-list)) - (let ((path-remote (concat root-remote (ssh-deploy--get-relative-path root-local path-local)))) - (let ((old-directory default-directory)) - (require 'shell) - (message "Opening eshell on '%s'.." path-remote) - (let ((default-directory path-remote)) - (shell path-remote))))))) + (ssh-deploy--file-is-included path-local exclude-list)) + (let ((path-remote (concat root-remote (ssh-deploy--get-relative-path root-local path-local)))) + (let ((old-directory default-directory)) + (require 'shell) + (message "Opening eshell on '%s'.." path-remote) + (let ((default-directory path-remote) + (explicit-shell-file-name ssh-deploy-remote-shell-executable)) + (shell path-remote))))))) ;;;### autoload (defun ssh-deploy-store-revision (path &optional root) @@ -1205,6 +1326,18 @@ '("Download" . ssh-deploy-download-handler)) +;;; Mode Line + + +;;;###autoload +(define-minor-mode ssh-deploy-line-mode + "Show SSH Deploy status in mode line" + :global t + :group 'ssh-deploy + (add-to-list 'global-mode-string 'ssh-deploy--mode-line-status-text t)) +(ssh-deploy--mode-line-status-refresh) + + (provide 'ssh-deploy) ;;; ssh-deploy.el ends here