9

Given the following modeline configuration:

(setq-default mode-line-format
   (list
    ;; Current buffer name
    "%b "
    ;; Major mode
    "[%m] "
    ;; Modified status
    "[%*] "
    ;; Cursor position
    "Line: %l/%i Column: %c"))

I would like for the last item to appear right-aligned.

  • 1
    Here is a link to a related thread: stackoverflow.com/q/16775855/2112489 – lawlist Dec 18 '14 at 16:53
  • 1
    Since you asked for a specific mode-line-format this isn't a proper answer, but smart-mode-line right-aligns the mode-line-misc-info by default, and it can right-align the list of minor-modes by setting sml/mode-width to 'right. – Malabarba Dec 18 '14 at 21:51
10

Like the answer in the comments, you can do this yourself by writing code to return a nicely spaced string.

Here is a simple way that supports only left and right aligned text applied to your specifications.

;; write a function to do the spacing
(defun simple-mode-line-render (left right)
  "Return a string of `window-width' length containing LEFT, and RIGHT
 aligned respectively."
  (let* ((available-width (- (window-width) (length left) 2)))
    (format (format " %%s %%%ds " available-width) left right)))


;; use the function in conjunction with :eval and format-mode-line in your mode-line-format
(setq mode-line-format
      '((:eval (simple-mode-line-render
                ;; left
                (format-mode-line "%b [%m] [%*]")
                ;; right
                (format-mode-line "Line: %l/%i Column: %c")))))

it ends up looking like this: enter image description here

Also note, I used your mode-line-format args as you specified, but I believe your are using %i incorrectly, which prints the byte size of the buffer, not the number of lines. You can use something like (line-number-at-pos (point-max)) to get the number of lines in your buffer.

  • One addition - you need to use window-total-width to calculate also linum and fringes additional paddings. – sandric Jul 16 '16 at 22:59
  • This answer has a bug where there returned mode-line will be evaluated again as a mode-line. Meaning % characters will attempt to be formatted twice. Accounted for this in my answer, emacs.stackexchange.com/a/37270/2418 -- also use window-total-width (thanks!) – ideasman42 Nov 5 '18 at 21:06
  • Resolved the bug in this answer: emacs.stackexchange.com/a/37270/2418 – ideasman42 Jun 13 at 10:29
2

To expand on @jordon-biondo's answer and resolve a bug showing %.

This example shows how mode mode line variables can be used with alignment - which took me a while to figure out.

(defun simple-mode-line-render (left right)
  "Return a string of `window-width' length containing LEFT, and RIGHT aligned respectively."
  (let* ((available-width (- (window-total-width) (+ (length (format-mode-line left)) (length (format-mode-line right))))))
    (append left (list (format (format "%%%ds" available-width) "")) right)
    )
  )

(setq-default
  mode-line-format
  '
  (
    (:eval
      (simple-mode-line-render
        ;; left
        (quote ("%e " mode-line-buffer-identification " %l : %c" evil-mode-line-tag "[%*]"))
        ;; right
        (quote ("%p " mode-line-frame-identification mode-line-modes mode-line-misc-info))
        )
      )
    )
  )
)

Example output:

init.el 1 : 0 <N> [-] Top -F1 (Emacs-Lisp WK ivy drag AC GitGutter)

0

This isn't supported out-of-the-box but the smart-mode-line package does support this. You could either use that package, or if it does more than what you want, extract just the bits that implement the feature you are asking for.

  • Since the op did not follow up, I have turned @Malabarba's comment into an answer. This way the question isn't "unanswered" and this package might very well be what other users having the same question would want to use. – tarsius Jan 18 '15 at 11:14
  • That's what I ended up doing, extracting the relevant functionality from smart-mode-line and adding it to my dotemacs. It requires me figuring out how much space I want to the right, but it's better than nothing. Unless someone posts a way to get rid of the manual char counting, I won't accept an answer, though. – mkaito Jan 18 '15 at 15:56
0

While it's possible to do 'correct' left/right alignment adding an alternative method because fully evaluating the left and right just for alignment is a bit heavy, when there is a simpler alternative.

If you know you only need a fixed amount of space on the right, you can fill in all but N characters, this works as long as the right size is a fixed length.

String formatting %12s and similar can be used to ensure the string doesn't resize.

(defun mode-line-fill (face reserve)
  "Return empty space using FACE and leaving RESERVE space on the right."
  (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
    )
  )

(setq-default
  mode-line-format
  (list
    ;; left align
    "%e %b [%*]"
    ;; right align
    (mode-line-fill 'mode-line 18)
    "%6l, %4c, %8p"
    )
  )
)

Eg:

CMakeLists.txt [-] 1590, 0, 94%

Note that this only works well if you want to display a few items on the right hand side, as with this example - line/column/percentage. Showing all minor modes for eg wouldn't work well.

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.