4

I want to customize mode-line-format using if or cond etc., to let it show different text conditionally.

Here is a demo that I tried:

(setq-default
 mode-line-format
 (quote
  (
   (:eval
    (cond
     (buffer-read-only
      (propertize " ⚑ "
                  'face (:foreground "red" :weight 'bold)
                  'help-echo "buffer is read-only!!!"))
     ;; (overwrite-mode
     ;;  (propertize "??"))
     (buffer-modified-p
      (propertize " ☡ "
                  'face (:foreground "orange")
                  'help-echo "buffer modified."))
     ))

   (:eval (if (or (eq (buffer-local-value 'major-mode (current-buffer)) 'ruby-mode)
                 (eq (buffer-local-value 'major-mode (current-buffer)) 'enh-ruby-mode))
              (:propertize "Ruby"
                           face (:foreground "green"))
            (:propertize "Not Ruby"
                         face (:foreground "orange"))))
   )))

But it does not show anything, I don't know where is wrong. Need help.

BTW:

I googled this, And got two good results:

And I saw two different code:

(setq-default
 mode-line-format
 '(
   (:propertize var
                'face (:foreground "green"))
   ))

(setq-default
 mode-line-format
 (list
   '(:eval (if ...))
   ))

I don't know what's the difference.

---------------- UPDATE ---------------------

I found I can't put multiple (propertize ...) in one (progn ...). Is there any solution to solve this?

(setq-default
 mode-line-format
'(
  (:eval
    (if (memq (buffer-local-value 'major-mode (current-buffer))
              '(ruby-mode enh-ruby-mode))
        (progn
          (propertize " ("
                      'face '(:foreground "#444444"))
          (propertize "Ruby: "
                      'face '(:family "Segoe Print"
                                      :height 80
                                      :foreground "red2"))
          (propertize (rbenv--active-ruby-version) ; `rbenv--modestring'
                      'face '(:foreground "cyan")
                      'help-echo '(concat "\nCurrent Ruby version: " (rbenv--active-ruby-version)
                                          "\nmouse-1: switch Ruby version menu")
                      ;; 'local-map
                      )
          (propertize ")"
                      'face '(:foreground "#444444"))
          )
      ;; (propertize "Not Ruby"
      ;;             'face '(:foreground "red2"))
      ))
))

This is solved, use (list (propertize ...) (propertize ...).

  • I love the flag! – lawlist Jul 3 '15 at 2:21
3

If you want something that changes according to conditions then you pretty much need to use :eval, as in the second borrowed-code snippet.

There are several things wrong with your code. buffer-modified-p is a function, not a variable; you forgot to quote some things; etc. Try this, and then compare it carefully with your code:

(setq-default mode-line-format
              '((:eval
                 (cond
                   (buffer-read-only
                    (propertize " ⚑ "
                                'face '(:foreground "red" :weight 'bold)
                                'help-echo "buffer is read-only!!!"))
                   ((buffer-modified-p)
                    (propertize " ☡ "
                                'face '(:foreground "orange")
                                'help-echo "buffer modified."))))
                (:eval (if (memq (buffer-local-value 'major-mode (current-buffer))
                                 '(ruby-mode enh-ruby-mode))
                           (propertize "Ruby" 'face '(:foreground "green"))
                         (propertize "Not Ruby" 'face '(:foreground "orange")))))) 
  • Why need to quote those things, I'm confused. Can you tell me why? Or just give me some hints. – stardiviner Jul 3 '15 at 3:36
  • What if I want to display a symbol like mode-line-process, I use (propertize 'mode-line-process 'face '(:foreground "orange")) does not work. Why? – stardiviner Jul 3 '15 at 4:22
  • 1
    You need to quote things like the symbol face because :eval will try to evaluate them. You can try it yourself: Select the sexp in your code that is inside the :eval, and use M-: to evaluate it (after turning on debug-on-error. You will see the error raised. That is generally a good way to debug mode-line-format stuff. – Drew Jul 3 '15 at 14:59
  • 2
    You don't want to propertize the symbol mode-line-process (presumably). You want to propertize its value, which is a string (presumably). You need to spend some time with the Emacs doc (including the manual Intro to Emacs Lisp) and spend some time experimenting with evaluating simple sexps. mode-line-format, especially with the use of :eval, is probably not the best place to start. – Drew Jul 3 '15 at 15:01

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.