6

I have installed nyan-mode and mode line looks like this.

enter image description here

I would like to move nyan cat to end of mode line and arrange all other items like column number, file name, modes to left side leaving empty space in middle.

How can i re arrange items in mode line?

2 Answers 2

3

For customizations your describe you're going to have to write your own mode-line-format.

You should read the docs for the variable mode-line-format to understand how to get the information you want into the mode-line. However, there is no left, center, and right justification support for mode-line information by default. You have to write your own by calculating the size of the current window and spacing things out with the right amount of whitespace such that it fills the whole window.

Most mode-line packages like powerline implement this in an exposed way that you can use if you want to rely on that package. Look at the provided formats that come with powerline and you should be able to deduce how to use powerline to have left, center, and right mode-line information using their api.

If you'd like to do it yourself, here is a function that I use to space out items in my mode line to the left, right and center.

(defun jordon-fancy-mode-line-render (left center right &optional lpad rpad)
  "Return a string the width of the current window with 
LEFT, CENTER, and RIGHT spaced out accordingly, LPAD and RPAD,
can be used to add a number of spaces to the front and back of the string."
  (condition-case err
      (let* ((left (if lpad (concat (make-string lpad ?\s) left) left))
             (right (if rpad (concat right (make-string rpad ?\s)) right))
             (width (apply '+ (window-width) (let ((m (window-margins))) (list (or (car m) 0) (or (cdr m) 0)))))
             (total-length (+ (length left) (length center) (length right) 2)))
        (when (> total-length width) (setq left "" right ""))
        (let* ((left-space (/ (- width (length center)) 2))
               (right-space (- width left-space (length center)))
               (lspaces (max (- left-space (length left)) 1))
               (rspaces (max (- right-space (length right)) 1 0)))
          (concat left (make-string lspaces  ?\s)
                  center
                  (make-string rspaces ?\s)
                  right)))
    (error (format "[%s]: (%s) (%s) (%s)" err left center right))))

And this is my mode-line-format which uses the function:

(defvar jordon-mode-line-format
  '((:eval (jordon-fancy-mode-line-render
            (format-mode-line (format " %s (%%l/%d) %%c "
                                      (downcase (format-mode-line mode-name))
                                      (line-number-at-pos (point-max))))
            (concat (buffer-name)
                    (cond
                     ((not (buffer-file-name)) " ")
                     ((buffer-modified-p) "*")
                     (t " ")))
            " " 1 3))))

In this example, I have the mode-name, and cursor position on the left, the buffer name in the middle, and nothing on the right. You could use that as a base to add in the info you need, and put the nyan cat on the left.

Here is a basic mode-line-format that just has the mode-name on the left, buffer-name in the center, and the nyan-cat on the right.

(defvar your-custom-mode-line-format
  '((:eval (jordon-fancy-mode-line-render
            (downcase (format-mode-line mode-name))
            (buffer-name)
            (nyan-create) 
            1 1))))

Which looks like this: enter image description here

4

You can use the following code and adjust mode-line-align-left, mode-line-align-middle and mode-line-align-right to your liking.

(setq-default mode-line-format
              (list
               mode-line-align-left
               '(:eval (mode-line-fill-center 'mode-line
                                              (reserve-left/middle)))
               mode-line-align-middle
               '(:eval
                 (mode-line-fill-right 'mode-line
                                       (reserve-middle/right)))
               mode-line-align-right
               ))

Here is the code you need to make this work. I don't know where I got this from, the filling functions are taken from powerline if I remember correctly.

(defun mode-line-fill-right (face reserve)
  "Return empty space using FACE and leaving RESERVE space on the right."
  (unless reserve
    (setq reserve 20))
  (when (and window-system (eq 'right (get-scroll-bar-mode)))
    (setq reserve (- reserve 3)))
  (propertize " "
              'display `((space :align-to (- (+ right right-fringe right-margin) ,reserve)))
              'face face))


(defun mode-line-fill-center (face reserve)
  "Return empty space using FACE to the center of remaining space leaving RESERVE space on the right."
  (unless reserve
    (setq reserve 20))
  (when (and window-system (eq 'right (get-scroll-bar-mode)))
    (setq reserve (- reserve 3)))
  (propertize " "
              'display `((space :align-to (- (+ center (.5 . right-margin)) ,reserve
                                             (.5 . left-margin))))
              'face face))




(defconst RIGHT_PADDING 1)


(defun reserve-left/middle ()
  (/ (length (format-mode-line mode-line-align-middle)) 2))

(defun reserve-middle/right ()
  (+ RIGHT_PADDING (length (format-mode-line mode-line-align-right))))

To read more about the formatting rules of the mode line I recommend this[archive-link] blog post. Here is a short example how you might want to define mode-line-align-left/middle/right:

(setq mode-line-align-left
      '(""
        " "
        (:propertize "%+ " face mode-line-buffer-id)
        (:propertize "%b" face mode-line-buffer-id)
        " "))

(setq mode-line-align-middle
      '(""
        (:propertize (:eval (symbol-name major-mode)) face font-lock-type-face)
        " "
        ))


(setq mode-line-align-right
      '(""
        (:propertize (:eval (shorten-directory default-directory 30)) face font-lock-string-face)
        ))
1
  • Wow, this is the only place I've seen something like this and it's exactly what I was looking for
    – GammaGames
    Commented Jun 24, 2020 at 5:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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