1

I want to call some methods in the Emacs mode-line format. For example count-words to see how many characters are selected or what's the class/method name cursor is on.

This is my current mode-line format, but calling count-words, it shows *invalid* as a result and also I'm not sure that it will be invoked in any changes.

(setq-default mode-line-format
      (list "---File:[%b%+] Line:[%l] Size:[%i] "
        (count-words (point-min) (point-max))
        ))

I want to call some custom methods in the mode-line area which are updating frequently. For example, how many characters I've selected, who changed this line (git blame), what is the current class name which the cursor is on now, and so on.

mortymacs
  • 3,456
  • 3
  • 27
  • 53
  • Note that you are evaluating `(count-words (point-min) (point-max))` at the time you set the variable, and therefore the list value you've generated just contains the literal integer word count value for whichever buffer was current at the time that code ran. So you're setting the default value of `mode-line-format` to something like `("---File:..." 873)` – phils Nov 24 '19 at 23:44

2 Answers2

3

The answer to the question you have asked is:

(setq mode-line-format
  (list "---File:[%b%+] Line:[%l] Size:[%i] %d"
    (format "count: %d" (count-words (point-min) (point-max)))))

But I don't think that is the question you meant to ask, because the value won't update. Let's fix that.

I've chosen to have it update after you save the file because the counting the words in buffer is going to get v slow at some buffer size if you are doing it frequently.

(setq mode-line-format
      (list "---File:[%b%+] Line:[%l] Size:[%i] %d"
        'count-words-string))

(defun update-count-words-string-for-modeline ()
  (interactive)
  (setq count-words-string 
        (format "word count: %d" (count-words (point-min) (point-max))))
  (force-mode-line-update))

(add-hook 'after-save-hook 'update-count-words-string-for-modeline)

(It might equally suit your purposes to simply call message with the word count after saving.)

Realraptor
  • 169
  • 5
  • Thanks for your answer. Actually, I want to get count of selected text. So, putting an event in on-save and so on doesn't help much. Do you have any idea about a live changes? (e.g. selected text, ...) – mortymacs Nov 23 '19 at 11:30
  • `M--` runs `count-words-region` which will write a message to the bottom line of the screen and to the `*Messsages*` buffer. Is that what you want? Otherwise, we could write a function to count words and characters and bind it to a key. But we need to understand _exactly_ what you want. – Realraptor Nov 23 '19 at 17:47
  • I want to call some custom methods in the mode-line area which are updating frequently. For example, how many characters I've selected, who changed this line (git blame), what is the current class name which the cursor is on now, and so on. – mortymacs Nov 23 '19 at 18:07
1
‘(:eval FORM)’
     A list whose first element is the symbol ‘:eval’ says to evaluate
     FORM, and use the result as a string to display.  Make sure this
     evaluation cannot load any files, as doing so could cause infinite
     recursion.

-- C-hig (elisp)Mode Line Data

In general, avoid using :eval if you don't need to. In many cases it will be more efficient to display the value of a variable in the mode line, and arrange elsewhere for that variable to be updated whenever necessary (which may be far less frequently than the mode line is redisplayed).

Your example of calling count-words on the entire buffer might cause performance issues in large buffers.

Example:

(setq-default mode-line-format '(:eval (count-words--buffer-message)))
phils
  • 71,335
  • 11
  • 153
  • 198
  • Thanks for your answer. May I ask you to put a sample? Because I'm trying to use but it returns empty or it mentions it's the void result. Well, I want to show the count of the selected text for example. Thank you. – mortymacs Nov 24 '19 at 12:09
  • I've added an example. It's not a *practical* example -- `count-words--buffer-message` calls `message`, so this is going to generate a lot of unwanted noise -- but it was the easiest way to put the interactive `count-words` output into the mode line. – phils Nov 24 '19 at 21:03