Skip to content

Instantly share code, notes, and snippets.

@Yevgnen
Last active July 25, 2017 11:56
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Yevgnen/9067fcc025caa084d2fa7ae1d65315af to your computer and use it in GitHub Desktop.
Save Yevgnen/9067fcc025caa084d2fa7ae1d65315af to your computer and use it in GitHub Desktop.
(require 'subr-x)
(require 'projectile)
(defvar ivy--switch-buffer-name-max-length 40)
(defvar ivy--switch-buffer-mode-max-length 18)
(defvar ivy--switch-buffer-project-max-length 15)
(defvar ivy--switch-buffer-delimiter "")
(defun ivy--switch-buffer-pad (str len)
(concat str (make-string (- len (length str)) ? )))
(defun ivy--switch-buffer-mode (mode)
(capitalize
(replace-regexp-in-string "-" " " (replace-regexp-in-string "-mode" "" (symbol-name major-mode)))))
(defun ivy--switch-buffer-user-buffer-p (name)
(not (string-match "^\\*" str)))
(defun ivy--switch-buffer-excluded-modes-p (modes)
(not (memq major-mode modes)))
(defun ivy--switch-buffer-shorten-path (file)
(replace-regexp-in-string "\\/?.+?\\/\\(.+\\)\\/.+?\\/.*" "…" file nil nil 1))
(defun ivy-switch-buffer-rich-transformer (str)
(let ((buf (get-buffer str)))
(if buf
(with-current-buffer buf
(let* (;; Indicators
(modified (propertize (if (and (buffer-modified-p)
(ivy--switch-buffer-excluded-modes-p '(dired-mode shell-mode))
(ivy--switch-buffer-user-buffer-p str))
"*"
"")
'face 'error))
(readonly (propertize (if (and buffer-read-only
(ivy--switch-buffer-user-buffer-p str))
"!"
"")
'face 'error))
(process (propertize (if (get-buffer-process (current-buffer))
"&"
"")
'face 'error))
(indicator (ivy--switch-buffer-pad (format "%s%s%s" readonly modified process) 3))
;; Buffer name
(name (ivy--switch-buffer-pad str ivy--switch-buffer-name-max-length))
(name (propertize name 'face 'ivy-modified-buffer))
;; Major mode
(mode (ivy--switch-buffer-pad (ivy--switch-buffer-mode major-mode) ivy--switch-buffer-mode-max-length))
(mode (propertize mode 'face 'warning))
;; Project
(project (projectile-project-name))
(project (propertize (ivy--switch-buffer-pad
(if (string= project "-")
""
project)
ivy--switch-buffer-project-max-length)
'face 'success))
(project-home (if (or (string-empty-p project)
(not (projectile-project-p)))
""
(file-truename (projectile-project-root))))
;; Path
(path-max-length (- (window-width (minibuffer-window))
ivy--switch-buffer-name-max-length
(length indicator)
ivy--switch-buffer-mode-max-length
ivy--switch-buffer-project-max-length))
(path (file-truename (or (buffer-file-name) default-directory)))
(path (if (string-empty-p project)
path
(substring-no-properties path (length project-home))))
(path (if (> (length path) path-max-length)
(ivy--switch-buffer-shorten-path path)
path))
(path (ivy--switch-buffer-pad path path-max-length))
(display (format "%s%s%s%s%s%s%s%s"
name indicator ivy--switch-buffer-delimiter
mode ivy--switch-buffer-delimiter
project ivy--switch-buffer-delimiter
path)))
display))
str)))
(ivy-set-display-transformer
'ivy-switch-buffer 'ivy-switch-buffer-rich-transformer)
(provide 'ivy-switch-buffer-rich)
@abo-abo
Copy link

abo-abo commented Nov 18, 2016

Looks good. You should consider making this a MELPA package

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment