6

I want to make names of major modes shorter. No longer than three characters. Is there any packages that do something like that?

It's better to shorten mode names in automatic fashion, so one doesn't need to constantly manage this thing manually. I'm ready to consider any principle of shortening. Most trivial would be to use abbreviations, so emacs-lisp-mode would become el, for example. interactive-haskell-mode would become ih. Not bad at all for a start.

I also like Unicode characters like Greek letters and other stuff to be mode names, currently I use sort of hack to “rename” modes, but maybe there is full featured package to do it?


Clarification: the question is about mode names (values of variable mode-name usually), they are displayed in mode line. I want to make major mode “lighters” shorter.

7
  • @Drew I believe he means in the mode-line. Sep 11, 2015 at 19:01
  • @Drew, now it should be clear. Sep 11, 2015 at 19:03
  • 2
    Was going to suggest diminish, but that's for minor modes. For my most frequently used modes, I simply set the mode-name in a mode hook to something very short. That takes care of 90% of my buffers with minimal setup.
    – Dan
    Sep 11, 2015 at 19:04
  • 4
    I haven't used it myself, but DelightedModes purports to handle major modes.
    – npostavs
    Sep 11, 2015 at 19:14
  • 1
    I added mention of the mode-line to the title. Note that mode-name is used in more than the mode-line. There could be solutions to the mode-line problem that do not change mode-name.
    – Drew
    Sep 11, 2015 at 20:04

4 Answers 4

7

Cyphejor can handle this. Here is how it works (copied from README.md file):

First you need to set value of variable cyphejor-rules. This variable contains rules that the package uses to generate new names for major modes from their symbol names (values of major-mode variable).

Value of cyphejor-rules should be a list. Every element of the list must be either a list:

(string replacement &rest parameters)

where string is a “word” in major mode symbol name, replacement is another string to be used instead, parameters is a list that may be empty but may have the following keywords in it as well:

  • :prefix — put it in the beginning of result string
  • :postfix — put it in the end of result string

Apart from elements of the form described above the following keywords are allowed (they influence the algorithm in general):

  • :downcase — replace words that are not specified explicitly with their first letter downcased

  • :upcase — replace words that are not specified explicitely with their first letter upcased

If nothing is specified, use word unchanged separating it from other words with spaces if necessary.

Example of setup:

(setq
 cyphejor-rules
 '(:upcase
   ("bookmark"    "→")
   ("buffer"      "β")
   ("diff"        "Δ")
   ("dired"       "δ")
   ("emacs"       "ε")
   ("fundamental" "Ⓕ")
   ("inferior"    "i" :prefix)
   ("interaction" "i" :prefix)
   ("interactive" "i" :prefix)
   ("lisp"        "λ" :postfix)
   ("menu"        "▤" :postfix)
   ("mode"        "")
   ("package"     "↓")
   ("python"      "π")
   ("shell"       "sh" :postfix)
   ("text"        "ξ")
   ("wdired"      "↯δ")))

Next, just enable cyphejor-mode in your configuration file:

(cyphejor-mode 1)
4

If you just want to always trim the mode name to a particular length, then how about this:

(defcustom mode-name-max-length 8
  "The number of characters after which a major mode name will be
  truncated in the modeline.")

(defun truncate-mode-name ()
  (setq mode-name (truncate-string-to-width mode-name mode-name-max-length nil nil 't)))

(add-hook 'after-change-major-mode-hook #'truncate-mode-name)

(Updated to use truncate-string-to-width with ELLIPSIS argument per the comments -- thanks!)

2
  • 1
    You should use elipsis argument of truncate-string-to-width. This will append ~ only when something is really truncated. This is an option but in many cases it will be unclear which mode it is because several modes start with the word "interactive" for example and it will be "interact~" for them all. Abbreviations would be better. There is no existing solution probably. I will need to think how this can be done... Sep 11, 2015 at 20:12
  • I agree, this is not very elegant. But I suspect a smarter approach to truncation will be difficult without simply defining a mapping from long name to short name. Mode names use different delimiters (e.g. "Emacs-Lisp" vs "REST Client") and you can't reliably guess whether the word before or after the delimiter is more significant. You could potentially use the first letter (or first few letters) of each word, I suppose. Personally I use "ELisp" to shorten "Emacs-Lisp", but don't think that would apply generally.
    – glucas
    Sep 11, 2015 at 20:22
0

You can also just get rid of the major mode lighter in the mode-line altogether.

Just take the code defining mode-line-modes from bindings.el, and comment-out or remove these lines, to try it out:

`(:propertize ("" mode-name)
              help-echo "Major mode\n\
mouse-1: Display major mode menu\n\
mouse-2: Show help for major mode\n\
mouse-3: Toggle minor modes"
              mouse-face mode-line-highlight
              local-map ,mode-line-major-mode-keymap)

Result:

(defvar mode-line-modes
  (let ((recursive-edit-help-echo "Recursive edit, type C-M-c to get out"))
    (list (propertize "%[" 'help-echo recursive-edit-help-echo)
          "("
;;;           `(:propertize ("" mode-name)
;;;                         help-echo "Major mode\n\
;;; mouse-1: Display major mode menu\n\
;;; mouse-2: Show help for major mode\n\
;;; mouse-3: Toggle minor modes"
;;;                         mouse-face mode-line-highlight
;;;                         local-map ,mode-line-major-mode-keymap)
          '("" mode-line-process)
          `(:propertize ("" minor-mode-alist)
                        mouse-face mode-line-highlight
                        help-echo "Minor mode\n\
mouse-1: Display minor mode menu\n\
mouse-2: Show help for minor mode\n\
mouse-3: Toggle minor modes"
                        local-map ,mode-line-minor-mode-keymap)
          (propertize "%n" 'help-echo "mouse-2: Remove narrowing from buffer"
                      'mouse-face 'mode-line-highlight
                      'local-map (make-mode-line-mouse-map
                                  'mouse-2 #'mode-line-widen))
          ")"
          (propertize "%]" 'help-echo recursive-edit-help-echo)
          " "))
  "Mode line construct for displaying major and minor modes.")
4
  • Wouldn't it be easier to set mode-name to empty string in after-change-major-mode-hook? Nevertheless I feel more comfortable when I see for example λ — this stands for Common Lisp mode, then I have other letter assigned to other modes. I wonder if we could have a table for frequently used parts of names, so we could define that word lisp should be replaced with λ, and maybe a couple of other rules. By default let's take first letter of word. So Common Lisp will be , Lisp Interaction mode could be λi, Emacs Lisp mode could be . I think it can be an interesting package… Sep 11, 2015 at 20:30
  • 1
    It's your question, so you get to decide what you want. ;-) My point was that you might well want to leave mode-name alone, as it is a general variable that can be used anywhere, and yet not have the mode name appear in the mode-line.
    – Drew
    Sep 11, 2015 at 20:39
  • This does satisfy the question "Make major-mode name shorter on the mode-line" since doing this would result in a length-zero mode-name (on the mode-line). Sep 15, 2015 at 19:53
  • 1
    @JonathanLeech-Pepin: Correct. Which is why I said "also" (meaning alternatively, here): you can also just get rid of it. I think this possibility is worth noting (and not only because zero chars is less than N>0 chars). An important consideration I wanted to point out, mentioned also in a comment I made to the question, is this: mode-name is a general, standard global variable that can be used in additional places. It's maybe not the wisest thing to wipe out its value just to reduce its effect on the mode-line.
    – Drew
    Sep 16, 2015 at 0:10
0

I really liked cyphejor to shorten the mode name in the mode line (I even threw in some emoji). But I missed the ability to filter by (regular) mode-name in ibuffer and other places.

So instead of activating cyphejor-mode, which actually alters mode-name, I just leave the mode off, and use its capabilities to replace the mode-name in the mode line, with caching to avoid recalculation:

  (defun my/cyphejor-with-cache ()
    (or (get major-mode 'cyphejor-cypher)
        (put major-mode 'cyphejor-cypher
         (cyphejor--cypher (symbol-name major-mode) cyphejor-rules))))
  (cl-nsubst '(:eval (my/cyphejor-with-cache)) 'mode-name
         (if minions-mode minions-mode-line-modes mode-line-modes))

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.