Skip to content

Mode Line

Dom Charlesworth edited this page Sep 12, 2016 · 9 revisions

modeline-with-icons

All the Icons is perfect for customising your mode line. Iconography and Icon Fonts and extremely good at conveying information without using too much space.

I made a couple of modifications to my Mode Line (as you can see in the above screenshot) which is based on Powerline. I have been maintaining my own version of Powerline which can be found here, so the following snippets of code are designed to work with that but that should still serve well as inspiration for how to customise your own mode line.

N.B. - You don't need Powerline to get icons in your Mode Line.

Snippets

Table of Contents

Modified or Read Only

This snippet displays a chain icon when the current file is saved, a broken chain when it is modified and a pad lock when the file is read only.

(defun custom-modeline-modified
  ((let* ((config-alist
            '(("*" all-the-icons-faicon-family all-the-icons-faicon "chain-broken" :height 1.2 :v-adjust -0.0)
              ("-" all-the-icons-faicon-family all-the-icons-faicon "link" :height 1.2 :v-adjust -0.0)
              ("%" all-the-icons-octicon-family all-the-icons-octicon "lock" :height 1.2 :v-adjust 0.1)))
           (result (cdr (assoc (format-mode-line "%*") config-alist))))
      (propertize (apply (cadr result) (cddr result))
                  'face `(:family ,(funcall (car result))))))

Window Numbers

This snippet displays a number icon for the number of the current window. This is designed to work with the Window Numbering package.

(defun custom-modeline-window-number ()
  (propertize (format " %c" (+ 9311 (window-numbering-get-number)))
              'face `(:height ,(/ (* 0.90 powerline/default-height) 100.0))
              'display '(raise 0.0)))

Mode Icon

This snippet displays the Developer Icon for the mode of that buffers file.

(defun custom-modeline-mode-icon ()
  (format " %s"
    (propertize icon
                'help-echo (format "Major-mode: `%s`" major-mode)
                'face `(:height 1.2 :family ,(all-the-icons-icon-family-for-buffer)))))

Region Marking

This snippet displays useful information on the current marked region, i.e. number of lines and characters marked.

(defun custom-modeline-region-info ()
  (when mark-active
    (let ((words (count-lines (region-beginning) (region-end)))
          (chars (count-words (region-end) (region-beginning))))
      (concat
       (propertize (format "   %s" (all-the-icons-octicon "pencil") words chars)
                   'face `(:family ,(all-the-icons-octicon-family))
                   'display '(raise -0.0))
       (propertize (format " (%s, %s)" words chars)
                   'face `(:height 0.9))))))

Version Control Icon

This snippet displays information about the current buffers version control system. Currently, it only supports SVN & Git for including icons.

(defun -custom-modeline-github-vc ()
  (let ((branch (mapconcat 'concat (cdr (split-string vc-mode "[:-]")) "-")))
    (concat
     (propertize (format " %s" (all-the-icons-alltheicon "git")) 'face `(:height 1.2) 'display '(raise -0.1))
     " · "
     (propertize (format "%s" (all-the-icons-octicon "git-branch"))
                 'face `(:height 1.3 :family ,(all-the-icons-octicon-family))
                 'display '(raise -0.1))
     (propertize (format " %s" branch) 'face `(:height 0.9)))))

(defun -custom-modeline-svn-vc ()
  (let ((revision (cadr (split-string vc-mode "-"))))
    (concat
     (propertize (format " %s" (all-the-icons-faicon "cloud")) 'face `(:height 1.2) 'display '(raise -0.1))
     (propertize (format " · %s" revision) 'face `(:height 0.9)))))

(defun custom-modeline-icon-vc ()
  (when vc-mode
    (cond
      ((string-match "Git[:-]" vc-mode) (-custom-modeline-github-vc))
      ((string-match "SVN-" vc-mode) (-custom-modeline-svn-vc))
      (t (format "%s" vc-mode)))))

Flycheck Checker Information

This snippet displays information about the results of running Flycheck on the current buffer. It doesn't actually use all-the-icons but it does look nicer, and could use it.

(defun custom-modeline-flycheck-status ()
  (let* ((text (pcase flycheck-last-status-change
                (`finished (if flycheck-current-errors
                               (let ((count (let-alist (flycheck-count-errors flycheck-current-errors)
                                              (+ (or .warning 0) (or .error 0)))))
                                 (format "%s Issue%s" count (unless (eq 1 count) "s")))
                             "✔ No Issues"))
                (`running     "⟲ Running")
                (`no-checker  "⚠ No Checker")
                (`not-checked "✖ Disabled")
                (`errored     "⚠ Error")
                (`interrupted "⛔ Interrupted")
                (`suspicious  ""))))
     (propertize text
                 'help-echo "Show Flycheck Errors"
                 'mouse-face '(:box 1)
                 'local-map (make-mode-line-mouse-map
                             'mouse-1 (lambda () (interactive) (flycheck-list-errors)))))))

Number of Packages to Update

This snippet displays the number of packages that you last needed to update. This currently works every time you refresh your package archive list, so the number can get stale pretty quickly.

(defvar powerline/upgrades nil)

(defun powerline/count-upgrades ()
  (let ((buf (current-buffer)))
    (package-list-packages-no-fetch)
    (with-current-buffer "*Packages*"
      (setq powerline/upgrades (length (package-menu--find-upgrades))))
    (switch-to-buffer buf)))
(advice-add 'package-menu-execute :after 'powerline/count-upgrades)

(defun custom-modeline-package-updates ()
  (let ((num (or powerline/upgrades (powerline/count-upgrades))))
    (when (> num 0)
      (propertize
        (concat
         (propertize (format "%s" (all-the-icons-octicon "package"))
                     'face `(:family ,(all-the-icons-octicon-family) :height 1.2)
                     'display '(raise -0.1))
         (propertize (format " %d updates " num)
                     'face `(:height 0.9)))
        'help-echo "Open Packages Menu"
        'mouse-face '(:box 1)
        'local-map (make-mode-line-mouse-map
                    'mouse-1 (lambda () (interactive) (package-list-packages)))))))

Weather Summary

This snippet displays the current time, the sunrise, sunset, current weather and the current temperature. It uses (and depends on) the Yahoo Weather package.

(defun custom-modeline-suntime ()
  (if (and (boundp 'yahoo-weather-info) yahoo-weather-mode)
      (concat
         (format "%s "(yahoo-weather-info-format yahoo-weather-info "%(sunrise-time)"))
         (format "%s  " (all-the-icons-wicon "sunrise" :height 0.5 :v-adjust -0.1)) 
         (format "%s "(yahoo-weather-info-format yahoo-weather-info "%(sunset-time)")) 
         (format "%s "(all-the-icons-wicon "sunset" :height 0.5 :v-adjust -0.1)))
    ""))
    
(defun custom-modeline-weather ()
  (if (and (boundp 'yahoo-weather-info) yahoo-weather-mode)
      (let* ((weather (yahoo-weather-info-format yahoo-weather-info format))
             (icon (all-the-icons-icon-for-weather (downcase weather)))
             (family (if (> (length icon) 2)
                         (face-attribute 'default :family)
                       (all-the-icons-wicon-family))))
        (propertize (format " %s " icon)
                    'help-echo weather
                    'face `(:height 1.0 :family ,family)
                    'display '(raise 0.1)))
  ""))

Time with an Icon Clock

This snippet displays the current time with a little clock icon which represents the current Hour (i.e. a clock face where the minute hand doesn't move)

(defun custom-modeline-time ()
  (let* ((hour (string-to-number (format-time-string "%I")))
         (icon (all-the-icons-wicon (format "time-%s" hour) :height 1.3 :v-adjust 0.0)))
    (concat
     (propertize (format-time-string " %H:%M ") 'face `(:height 0.9))
     (propertize (format "%s " icon) 'face `(:height 1.0 :family ,(all-the-icons-wicon-family)) 'display '(raise -0.0)))))
  
  

A Thrown Together Mode Line Function

With all of the above snippets defined, you should be able to create a mode line using them by setting mode-line-format to the following.

(setq mode-line-format '("%e" (:eval 
  (concat
    (custom-modeline-modified)
    (custom-modeline-window-number)
    (custom-modeline-mode-icon)
    (custom-modeline-icon-vc)
    (custom-modeline-region-info)
    (custom-modeline-flycheck-status)
    (custom-modeline-suntime)
    (custom-modeline-weather)
    (custom-modeline-time)))))

This gives you a basic idea of being able to customise parts of your mode line, I know the above won't look quite right but it's a start! I'd be happy to help if you have any questions of how I got my mode line to look the way that it does. So feel free to raise an issue

▲ back to top