seagle0128 / doom-modeline

A fancy and fast mode-line inspired by minimalism design.
https://seagle0128.github.io/doom-modeline/
GNU General Public License v3.0
1.3k stars 158 forks source link

Add option to truncate buffer-name #396

Closed mohkale closed 3 years ago

mohkale commented 3 years ago

Is your feature request related to a problem? Please describe. Sometimes I find myself in buffers with really long names (eg. *Org Src init.org[ emacs-lisp ]*) and these names end up overshadowing the rest of the mode-line. Most of the time only the first few characters are relevent so I'd like an option to truncate the buffer-file-name if it gets too long.

Describe the solution you'd like A new customization option doom-modeline-buffer-name-length which if non-nil should state the maximum length of a buffers-name in the mode-line. If a buffers name exceeds this length it should be truncated and the suffix repalced with another new option doom-modeline-buffer-name-ellipses.

For example: foo-bar-baz-bag -> foo-... when the maximum length is 6. The ellipses should contribute to the total length of the buffer name. If the length of the ellipses is less than or equal to doom-modeline-buffer-name-length then that should be a user-error.

Describe alternatives you've considered

(defvar +modeline-buffer-id-max-length 25
  "Truncate the buffer-id when it's larger than this many characters.
Set to nil to disable buffer-name truncation.")

(defvar +modeline-buffer-id-ellipses "..."
  "Suffix to be attached to truncated buffer names.")

(advice-add #'doom-modeline--buffer-name :filter-return
            (defun doom-modeline-buffer-name-truncate+ (val)
              (when val
                (let ((name (format-mode-line val)))
                  (if (and (eval-when-compile (< (length +modeline-buffer-id-ellipses)
                                                 +modeline-buffer-id-max-length))
                           (> (length name) +modeline-buffer-id-max-length))
                      (apply #'propertize
                             (concat
                              (substring-no-properties name 0
                                                       (eval-when-compile
                                                         (- +modeline-buffer-id-max-length
                                                            (length +modeline-buffer-id-ellipses))))
                              +modeline-buffer-id-ellipses)
                             (text-properties-at 0 val))
                    name)))))

Additional context

seagle0128 commented 3 years ago

Do you have a chance to check doom-modeline-buffer-file-name-style?

mohkale commented 3 years ago

Yes. Are you suggesting this won't be practical as an option when considering all the variety of formats that the buffer-name can be represented? Truncating ~/foo/bar to ~/foo/... isn't really useful. I'm OK with just supporting this for buffer-name or file-name; otherwise I suppose I'd understand if you'd close this issue.

seagle0128 commented 3 years ago

I am closing it.

codygman commented 3 years ago

This is even more needed if you use doom-modeline with exwm as seen in the screenshot. I could shorten the buffer name itself but that would hinder the usefulness of buffer switching because I couldn't match text in the buffer names.

screen

codygman commented 3 years ago

It looks like this solution might work for those who want to fix this issue now: https://www.reddit.com/r/DoomEmacs/comments/ie96qy/truncating_buffer_name_on_mode_line_doommodeline/g2fzrdm

seagle0128 commented 3 years ago

Thanks, @codygman !

mooseyboots commented 3 years ago

i would also like to be able to do this (using doom modeline in vanilla emacs 26.1), for long pdf files names where i still need to see the other info like current page number.

i tried adapting this solution for powerline, https://www.reddit.com/r/emacs/comments/4mhphb/spacemacs_how_to_limit_the_length_of_displayed/d3vphn9/ like so:

(require 'nadvice)

(defun my-truncate-buffer-name (buf-name)
  (let ((len (length buf-name)))
    (cond ((> len 20)
           (concat (substring buf-name 0 10)
                   "..."
                   (substring buf-name (- len 7) len)))
          (t buf-name))))

(advice-add 'doom-modeline--buffer-name :filter-return 'my-truncate-buffer-name)

it almost works, or half works, sometimes it truncates, sometimes doesn't.

maybe a doom modeliner can improve on it, or confirm/deny if this is a possible workaround?

fw623 commented 3 years ago

I personally use the following now to truncate EXWM buffer names according to the window-width

(defun fw/s-truncate (len s &optional ellipsis)
  "Like `s-truncate' but
- return S when LEN is nil
- return empty string when len is shorter than ELLIPSIS"
  (declare (pure t) (side-effect-free t))
  (let ((ellipsis (or ellipsis "...")))
    (cond
     ((null len) s)
     ((< len (length ellipsis)) "")
     (t (s-truncate len s ellipsis)))))

(defun fw/doom-modeline-segment--buffer-info (orig-fn &rest args)
  "`doom-modeline-segment--buffer-info' but truncate for EXWM buffers."
  (fw/s-truncate
   (and (derived-mode-p 'exwm-mode)
    (max 15 (- (window-width) 45)))
   (format-mode-line (apply orig-fn args))
   "..."))
(advice-add #'doom-modeline-segment--buffer-info :around #'fw/doom-modeline-segment--buffer-info)