Malabarba / smart-mode-line

A powerful and beautiful mode-line for Emacs.
901 stars 54 forks source link

Limit buffer-identification lenght for very long file names #236

Open gusbrs opened 5 years ago

gusbrs commented 5 years ago

I've been trying to sort this for quite some time and I could finally spare some time for it. I'm a happy user of smart-mode-line, but there was one thing that was still bothering me. I occasionally have to work with very long file names and, when this happens, all the work smart-mode-line makes to shorten the path within the buffer-identification is not enough, and the mode list is blown out of the window width.

As far as I grasped, I could really only intervene in sml/generate-buffer-identification, for this is the central function for the purpose and is hooked here and there in the code. Furthermore, it's output is already propertized, so it's hard to mess with it after the fact. Anyway, the result I reached was (changes are marked by comments):

  (defun sml/generate-buffer-identification (&rest ignored)
    "Return fully propertized prefix+path+buffername.
Argument IGNORED is ignored."
    (setq sml/name-width-old sml/name-width)
    (setq sml/buffer-identification-filling nil)
    (when (or ;; Only calculate all this if it will actually be used
           (equal sml/mode-line-buffer-identification mode-line-buffer-identification)
           (member (cadr sml/mode-line-buffer-identification) mode-line-buffer-identification)
           (member sml/mode-line-buffer-identification mode-line-buffer-identification))
      (setq sml/buffer-identification
            (let* ((dir (sml/replacer (abbreviate-file-name (sml/get-directory))))
                   (sml/use-projectile-p (unless (or (not sml/projectile-loaded-p)
                                                     (and (buffer-file-name)
                                                          (file-remote-p (buffer-file-name))))
                                           sml/use-projectile-p))
                   (prefix (sml/get-prefix dir))
                   (bufname (sml/buffer-name))
                   (dirsize (max 0 (- (abs (or (cdr-safe sml/name-width) sml/name-width))
                                      (string-width prefix) (string-width bufname))))
                   (dirstring (funcall sml/shortener-func dir dirsize))
                   ;; my modifications, to shorten buffer-identification for long file names
                   (bufnamesize (max 0 (- (abs (or (cdr-safe sml/name-width) sml/name-width))
                                          (string-width prefix) (string-width dirstring))))
                   (bufname (truncate-string-to-width bufname bufnamesize))
                   ;; end of my modifications
                   )

              (propertize (concat (sml/propertize-prefix (replace-regexp-in-string "%" "%%" prefix))
                                  (propertize (replace-regexp-in-string "%" "%%" dirstring) 'face 'sml/folder)
                                  (propertize (replace-regexp-in-string "%" "%%" bufname) 'face 'sml/filename))
                          'help-echo (format "%s\n\nmouse-1: Previous buffer\nmouse-3: Next buffer"
                                             (or (buffer-file-name) (buffer-name)))
                          'mouse-face 'mode-line-highlight
                          'local-map   mode-line-buffer-identification-keymap)))))

The logic here is that, if after all the work smart-mode-line does to shorten the buffer-identification, it still exceeds name-width, I truncate bufname in a way that the buffer-identification will be the size of name-width.

The result looks like: smart-mode-line

I haven't thoroughly tested it yet, but it looks straightforward enough. But I will add it to my regular use in this form.

I'm also not sure if this would be desired behaviour for everyone (or to anyone else at all!), though it is for me. I bring it here in the hope it might be useful.

Thank you very much for the great package!

Malabarba commented 5 years ago

Thanks for the nice words! :-)

Because of my lack of time, I generally avoid making significant changes to my packages nowadays, so I'll refrain from adding this change to the package. Still it's always nice to see people using and hacking around packages I publish, so thanks for the comment!