customizing the mode-line



The mode-line is the emacs 'status bar', the bar just above the minibuffer
that shows various pieces of information, such as the buffer name, the major
mode, maybe the current line number, some indicators for active minor modes,
and so on. As I'm looking at it, it starts with 1<U:**- (which is:
input-method: latin-1-alt-postfix, buffer-coding-system: utf8-unix,
line-ending: unix-style, buffer is writable and buffer is modified – the
tooltips help).


As with just about anything in emacs, the mode-line can be customized just
the way you like. I give some example below, not because I think it is
necessarily the best way, but just to give you a bit of an example to
start with when making your own best-mode-line-ever.


I'm not going through all the details of the example, but let me highlight a
few things that make it a bit easier to understand.


First of all, the mode-line can be customized by setting the variable
mode-line-format; this variable becomes buffer-local automatically when
changed, so if you want to set it for all buffers, you'll need to use
setq-default in your .emacs (or equivalent). The format is quite similar
to the one for frame-title-format, which we discussed in setting the frame title a while back.


mode-line-format is a list of items which are evaluated, and put
together as a string which then ends up as the mode-line contents. These
properties can be any string. The following types of items can be used:



  • First, normal strings are just shown as-is;


  • Then, there are some special format parameters which will be replaced with
    their value in the mode-line, from the Emacs-documentation:


  %b -- print buffer name.      %f -- print visited file name.
%F -- print frame name.
%* -- print %, * or hyphen. %+ -- print *, % or hyphen.
%& is like %*, but ignore read-only-ness.
% means buffer is read-only and * means it is modified.
For a modified read-only buffer, %* gives % and %+ gives *.
%s -- print process status. %l -- print the current line number.
%c -- print the current column number (this makes editing slower).
To make the column number update correctly in all cases,
`column-number-mode' must be non-nil.
%i -- print the size of the buffer.
%I -- like %i, but use k, M, G, etc., to abbreviate.
%p -- print percent of buffer above top of window, or Top, Bot or All.
%P -- print percent of buffer above bottom of window, perhaps plus Top,
or print Bottom or All.
%n -- print Narrow if appropriate.
%t -- visited file is text or binary (if OS supports this distinction).
%z -- print mnemonics of keyboard, terminal, and buffer coding systems.
%Z -- like %z, but including the end-of-line format.
%e -- print error message about full memory.
%@ -- print @ or hyphen. @ means that default-directory is on a
remote machine.
%[ -- print one [ for each recursive editing level. %] similar.
%% -- print %. %- -- print infinitely many dashes.
Decimal digits after the % specify field width to which to pad.


  • Forms of the type (:eval ...) are evaluated each time the mode-line is
    drawn (just like the '%'-parameters) ; so, if you have a value that
    changes of the course your emacs session, you should use (:eval ...).

    For example, for your emacs-uptime you could use (:eval (emacs-uptime "%hh")); while the emacs-PID does not change, so simply you could simply
    use (format "PID:%d").



    The format parameter mentioned above are of evaluated each time as
    well. Note that you have to be a bit careful with evaluations - don't do
    too heavy operations there, and be careful the updates don't recurse.




  • There are many others which I won't go into now - please check the Elisp
    reference. It's a rather baroque format…


Now, let's put this all together in an example (tested with emacs 23 and
24). As I said, this is for demonstration purposes only; but hopefully it
gives you some inspiration. A lot of the 'magic' (colors, tooltips, faces)
happens with the propertize function; again, the Elisp documentation can
tell you a lot more about that. I'm (ab)using the various font-lock-faces to
have colors that blend in nicely with your current theme.


And it has a limitation still, namely that it does not react to mouse clicks;
how to that, I will discuss in some future article.









;; use setq-default to set it for /all/ modes
(setq mode-line-format
(list
;; the buffer name; the file name as a tool tip
'(:eval (propertize "%b " 'face 'font-lock-keyword-face
'help-echo (buffer-file-name)))

;; line and column
"(" ;; '%02' to set to 2 chars at least; prevents flickering
(propertize "%02l" 'face 'font-lock-type-face) ","
(propertize "%02c" 'face 'font-lock-type-face)
") "

;; relative position, size of file
"["
(propertize "%p" 'face 'font-lock-constant-face) ;; % above top
"/"
(propertize "%I" 'face 'font-lock-constant-face) ;; size
"] "

;; the current major mode for the buffer.
"["

'(:eval (propertize "%m" 'face 'font-lock-string-face
'help-echo buffer-file-coding-system))
"] "


"[" ;; insert vs overwrite mode, input-method in a tooltip
'(:eval (propertize (if overwrite-mode "Ovr" "Ins")
'face 'font-lock-preprocessor-face
'help-echo (concat "Buffer is in "
(if overwrite-mode "overwrite" "insert") " mode")))

;; was this buffer modified since the last save?
'(:eval (when (buffer-modified-p)
(concat "," (propertize "Mod"
'face 'font-lock-warning-face
'help-echo "Buffer has been modified"))))

;; is this buffer read-only?
'(:eval (when buffer-read-only
(concat "," (propertize "RO"
'face 'font-lock-type-face
'help-echo "Buffer is read-only"))))
"] "

;; add the time, with the date and the emacs uptime in the tooltip
'(:eval (propertize (format-time-string "%H:%M")
'help-echo
(concat (format-time-string "%c; ")
(emacs-uptime "Uptime:%hh"))))
" --"
;; i don't want to see minor-modes; but if you want, uncomment this:
;; minor-mode-alist ;; list of minor modes
"%-" ;; fill with '-'
))

Have fun playing with this!


No comments:

Post a Comment

Followers

Popular Posts