help-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Extra info in modeline (tip and questions)


From: Decebal
Subject: Extra info in modeline (tip and questions)
Date: Tue, 14 Apr 2009 07:03:11 -0700 (PDT)
User-agent: G2/1.0

I would like to have some more info in my modeline. Default the number
of lines and the number of characters of the current buffer and in
text-mode also the number of words. I made something that is easy to
extend. I defined a vector whith the possible things to display and
pro buffer there is a vector with what to display.
The default is only lines and characters. This is done with:
    ;;; default lines and chars are displayed
    ;;; for nothing use nil
    (defvar mode-line-types
      (vector "lines" "chars")
      "*Types to dsiplay in the modeline."
      )
    (make-variable-buffer-local 'mode-line-types)

To display also words in text-mode, I use:
    (dolist (hook '(text-mode-hook))
      (add-hook hook (lambda ()
                       (setq mode-line-types (vector "lines" "words"
"chars"))
                       )
                )
      )

At the end of the post is the code.
I have a few questions:
- Can the code be written better? (I am relative new to elisp.)
- I tried to generalize. For example there is a function buffer-count-
words, which I would like to use also on a region of the buffer. But
when I call it interactively, it does not return anything. What do I
need to change?
- I defined two ways for counting words ("\\w+" and "[[:word:]\-]+").
Anyone a good idea for extending? (Almost every system counts words
diferently. It would be nice to have a mode which would give the same
count as the program that the other side is using. ;-] )

Ideas to make it better are offcourse welcome.

The code:
    ;;; includes
    (require 'cl)

    ;;; definitions
    (defstruct
      (mode-line-struct
       (:constructor nil)
       (:constructor new-mode-line-struct (type description display
function))
       )
      (type        nil :read-only t)
      (description nil :read-only t)
      (display     nil :read-only t)
      (function    nil :read-only t)
      )

    ;;; variables
    (setq mode-line-array
          (vector
           (new-mode-line-struct
            "chars"
            "Display number of chars"
            "C"
            'buffer-count-chars
            )
           (new-mode-line-struct
            "functions"
            "Display number of functions"
            "F"
            'buffer-count-functions
            )
           (new-mode-line-struct
            "lines"
            "Display number of lines"
            "L"
            'buffer-count-lines
            )
           (new-mode-line-struct
            "words"
            "Display number of words"
            "W"
            'buffer-count-words
            )
           )
          )

    (defvar buffer-mode-line
      nil
      "*Extension of modeline in the buffer."
      )

    (defvar word-type
      nil
      "*Type of word."
      )
    (make-variable-buffer-local 'word-type)

    ;;; default lines and chars are displayed
    ;;; for nothing use nil
    (defvar mode-line-types
      (vector "lines" "chars")
      "*Types to dsiplay in the modeline."
      )
    (make-variable-buffer-local 'mode-line-types)

    ;;; functions
    (defun buffer-count(expression &optional start end)
      (interactive "sExpression: \nr")
      (setq start (or start (point-min)))
      (setq end   (or end   (point-max)))
      (how-many expression start end)
      )

    (defun buffer-count-chars(&optional start end)
      (interactive "r")
      (number-to-string (buffer-count ".\\|\n" start end))
      )

    (defun buffer-count-functions(&optional start end)
      (interactive "r")
      (number-to-string (buffer-count "^(defun " start end))
      )

    (defun buffer-count-lines(&optional start end)
      (interactive "r")
      (number-to-string
       (+ (buffer-count "\n" start end) 1)
       )
      )

    (defun buffer-count-words(&optional start end)
      (interactive "r")
      (let ((regexp "\\w+"))
        (cond
         ((equal word-type "type1")
          (setq regexp "[[:word:]\-]+")
          )
         )
        (number-to-string (buffer-count regexp start end))
        )
      )

    (defun buffer-mode-line-extra()
      (let ((i         0)
            (mode-line " ")
            (total     (length mode-line-types))
            )
        (while (< i total)
          (setq mode-line
                (concat mode-line (get-mode-line-field (aref mode-line-
types i)))
                )
          (incf i)
          )
        mode-line
        )
      )

    (defun get-mode-line-field(type)
      (let ((i     0)
            (field (format "*%s*" type))
            (total (length mode-line-array))
            )
        (catch 'break
          (while (< i total)
            (if (equal type (mode-line-struct-type (aref mode-line-
array i)))
                (progn (setq field
                             (format "%s: %s "
                                     (mode-line-struct-display (aref
mode-line-array i))
                                     (funcall (mode-line-struct-
function (aref mode-line-array i)))
                                     )
                             )
                       (throw 'break nil)
                       )
              )
            (incf i)
            )
          )
        field
        )
      )

    (defun buffer-update-mode-line()
      (setq buffer-mode-line (buffer-mode-line-extra))
      (force-mode-line-update)
      )

    (unless buffer-mode-line
      (run-with-idle-timer 1 t 'buffer-update-mode-line)
      (buffer-update-mode-line)
      )

    (unless (memq 'buffer-mode-line global-mode-string)
      (setq global-mode-string
        (append global-mode-string
                '(" " buffer-mode-line)
                )
        )
      )


reply via email to

[Prev in Thread] Current Thread [Next in Thread]