For terminal, there is an app called byobu which shows different mode line based on host.

If I open terminal in system 1, mode line will be like this. enter image description here

If I ssh into system2 from system1, mode line will automatically changes to something like this. enter image description here

If I ssh into system3, mode line will change to something like this. enter image description here

In emacs, when I open a file/dired using tramp, I want to change mode line color automatically. How can I achieve that?

  • This related thread may contain the ingredients to formulate an answer -- Emacs — dired-mode test to determine remote server name / address: stackoverflow.com/q/24481381/2112489 With that solution, the original poster can assign different colors to the mode-line based upon the value returned . . . I use it to programmatically assign different directory listing switches on certain remote hosts because the ls versions are different. If the original poster needs more assistance on how to modify the mode-line-format, please advise. – lawlist Nov 10 '15 at 15:51

Like @lawlist said, determining if a file or directory is remote is easy and can be done using file-remote-p which will actually return the remote host is available.

You could then use find-file-hook and dired-mode-hook to check if the file is remote and if so assign the host a color(s) and use that color to determine the mode-line and mode-line-inactive faces and keep that color for all future opened files on that host.

To change the look of faces on per-buffer, use the face-remap lib included with emacs. Specifically, the face-remap-add-relative function.

Here is an implementation of this you can modify to suite your needs.

(defvar my-remote-buffer-colors
  (let ((colors '(("red" "darkred")
                  ("green" "darkgreen")
                  ("blue" "darkblue")
                  ("orange" "firebrick"))))
    (setcdr (last colors) colors)
  "Cyclic list of color combos to use for remote files. 
Elements are in the form: (active-background-color inactive-background-color).")

(defvar my-assigned-remote-colors (make-hash-table :test 'equal)
  "Hash table pairing remote hosts to mode-line color overrides.")

(defvar-local my-assigned-remote-color-cookies nil
  "Stores the face remap cookies created by `my-maybe-assign-remote-color' for removal if necessary.")

(defun my-maybe-assign-remote-color ()
  "If newly found file is remote assign it new modeline colors.

Colors are taken from `my-remote-buffer-colors', every file on the same remote
host will have the same colors, each newly accessed remote host will be assigned a new
color cycled from `my-remote-buffer-colors'."
  (let ((remote (file-remote-p default-directory)))
    (when remote
      (let ((color (or (gethash remote my-assigned-remote-colors) 
                       (puthash remote (pop my-remote-buffer-colors) my-assigned-remote-colors))))
        (setq my-assigned-remote-color-cookies
              (list (face-remap-add-relative 'mode-line (list :background (car color)))
                    (face-remap-add-relative 'mode-line-inactive (list :background (cadr color)))))))))

(add-hook 'find-file-hook 'my-maybe-assign-remote-color)
(add-hook 'dired-mode-hook 'my-maybe-assign-remote-color)
| improve this answer | |
  • I love that! Would it be possible to have colors variable be rather pattern based? Sort of (colors '(("/:myserver:/" "red" "darkred" (...))) ? I don't know LISP... :-/ I am sure it is trivial for you. – elixon Jul 26 '19 at 14:11
  • Maybe I can just somehow pre-insert values in my-assigned-remote-colors list? Would it be possible? – elixon Jul 26 '19 at 14:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.