Skip to content

Instantly share code, notes, and snippets.

@cameronwp
Last active October 24, 2022 15:53
Show Gist options
  • Save cameronwp/d4299a87eff1b896ea10e70fa4395d2a to your computer and use it in GitHub Desktop.
Save cameronwp/d4299a87eff1b896ea10e70fa4395d2a to your computer and use it in GitHub Desktop.
Fun with application window titles ([[https://tecosaur.github.io/emacs-config/config.html#window-title][format source]], [[https://www.reddit.com/r/emacs/comments/jtoomj/org_docs_get_title/][getting the title source]], [[https://emacsredux.com/blog/2020/06/14/checking-the-major-mode-in-emacs-lisp/][testing mode source]],
[[https://www.gnu.org/software/emacs/manual/html_node/elisp/_0025_002dConstructs.html][%-constructs]], [[https://emacs.stackexchange.com/a/45424/38020][getting path relative to project root source]]). When in org-mode, use the file title. Otherwise use the filename and project with
some exceptions. Indicate if the file has been modified. The desired end result is below.
(Assumes you're using projectile)
*Org Roam*
: Org Mode Title - Doom Emacs
: *Org Mode Title - Doom Emacs
*Files in a Project*
: Filename - Project Name - Doom Emacs
: *Filename - Project Name - Doom Emacs
Given a file at a path like ~src/foo/bar/file.lisp~
: s/f/b/file.lisp - Project Name - Doom Emacs
*When not in a project*
: Filename - Doom Emacs
: Compiling... - Doom Emacs
: sly - Doom Emacs
(This is the updated version after comments on Doom Discord)
#+begin_src emacs-lisp
(defun shorten-directory-name (pathpart)
"If no punctuation, return first letter. If there is a '-', '+', or '.' in the directory name, include it.
Examples: 'src' -> 's'. 'temporal-networks' -> 't-n'"
(let* ((match (string-match "[-\.\+]" pathpart))
(match-char (if match (substring pathpart match (1+ match)))))
(if match
;; if there is punctuation, split on it and get the first char from each part
(mapconcat (lambda (pp) (substring pp 0 1)) (split-string pathpart match-char) match-char)
;; no punctuation, just return the first char
(substring pathpart 0 1))))
(defun acronymize-path ()
"Get the acronym path, eg. `src/foo/bar/thing.lisp' -> `s/f/b/thing.lisp'. The punctuation marks `-', `+', and `.' in
dir names are kept"
(let* ((path-parts-within-project (split-string (file-relative-name buffer-file-name (projectile-project-root)) "/"))
;; shorten the directory names to single letters (or single letters separated by their punctuation)
(shortened-path-parts (mapconcat #'shorten-directory-name (butlast path-parts-within-project) "/")))
;; now join the shortened path with the filename
(if (not (string-empty-p shortened-path-parts))
(concat shortened-path-parts "/" (car (last path-parts-within-project)))
(car (last path-parts-within-project)))))
(setq frame-title-format
'(""
(:eval
(let* ((org-roam-p (s-contains-p org-roam-directory (or buffer-file-name "")))
(comint-mode-p (derived-mode-p 'comint-mode))
(messages-mode-p (derived-mode-p 'messages-buffer-mode))
(minibuf-mode-p (derived-mode-p 'minibuffer-mode))
(sly-mode-p (derived-mode-p 'sly-mrepl-mode))
(agenda-mode-p (derived-mode-p 'org-agenda-mode))
(treemacs-mode-p (derived-mode-p 'treemacs-mode))
(doom-dashboard-mode-p (derived-mode-p '+doom-dashboard-mode))
(fundamental-mode-p (derived-mode-p 'fundamental-mode))
(emacs-lisp-mode-p (derived-mode-p 'emacs-lisp-mode))
(project-name (projectile-project-name))
(project-p (and project-name (not (string= "-" project-name))))
;; FYI you can be in a project but not in a file, eg. when you're in a treemacs buffer
(acronymed-path (if (and project-p buffer-file-name) (acronymize-path)))
(show-project-p (and project-p
(not comint-mode-p)
(not org-roam-p)
(not doom-dashboard-mode-p)))
(show-modified-p (not (or agenda-mode-p
comint-mode-p
messages-mode-p
minibuf-mode-p
treemacs-mode-p
doom-dashboard-mode-p
fundamental-mode-p
;; technically not necessary bc sly repls are also in comint-mode
sly-mode-p)))
(specific-title (cond
;; FYI order matters. some buffers respond to multiple modes
(sly-mode-p "sly")
(comint-mode-p "Compiling...")
(messages-mode-p "Messages")
(minibuf-mode-p "Minibuffer")
(agenda-mode-p "Agenda")
(treemacs-mode-p "Tree")
(doom-dashboard-mode-p "Dashboard")
(emacs-lisp-mode-p "Emacs Lisp")
(fundamental-mode-p "Fundamental")
;; grabs the #+title of an org file
(org-roam-p (cadar (org-collect-keywords '("TITLE"))))
;; shorten paths to single letters in projects
(show-project-p acronymed-path)
;; just the filename for all other files
(t "%b"))))
(concat
(format (if (and (buffer-modified-p) show-modified-p) "*%s" "%s") specific-title)
(if show-project-p (format " - %s" project-name)))))
" - Doom Emacs"))
#+end_src
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment