Merge remote-tracking branch 'origin/develop' into download-iosevka

This commit is contained in:
James Ravn 2020-02-25 19:50:12 +00:00
commit 3a257cfc56
No known key found for this signature in database
GPG key ID: 52C372C72159D6EE
428 changed files with 9639 additions and 6497 deletions

View file

@ -3,21 +3,33 @@
(use-package! deft
:commands deft
:init
(setq deft-extensions '("org" "md" "tex" "txt")
deft-default-extension "org"
(setq deft-default-extension "org"
;; de-couples filename and note title:
deft-use-filename-as-title nil
deft-use-filter-string-for-filename t
deft-org-mode-title-prefix t
;; converts the filter string into a readable file-name using kebab-case:
deft-file-naming-rules
'((noslash . "-")
(nospace . "-")
(case-fn . downcase)))
'((noslash . "-")
(nospace . "-")
(case-fn . downcase)))
:config
(add-to-list 'deft-extensions "tex")
(add-hook 'deft-mode-hook #'doom-mark-buffer-as-real-h)
;; start filtering immediately
(set-evil-initial-state! 'deft-mode 'insert)
(map! :map deft-mode-map
:n "gr" #'deft-refresh
:n "C-s" #'deft-filter
:i "C-n" #'deft-new-file
:i "C-m" #'deft-new-file-named
:i "C-d" #'deft-delete-file
:i "C-r" #'deft-rename-file
:n "r" #'deft-rename-file
:n "a" #'deft-new-file
:n "A" #'deft-new-file-named
:n "d" #'deft-delete-file
:n "D" #'deft-archive-file
:n "q" #'kill-current-buffer
:localleader
"RET" #'deft-new-file-named
"a" #'deft-archive-file

View file

@ -1,4 +1,4 @@
;; -*- no-byte-compile: t; -*-
;;; ui/deft/packages.el
(package! deft)
(package! deft :pin "f54e8a65a7")

View file

@ -1,20 +1,88 @@
#+TITLE: ui/doom-dashboard
#+DATE: October 9, 2019
#+SINCE: v1.3
#+STARTUP: inlineimages
#+STARTUP: inlineimages nofold
* Table of Contents :TOC_3:noexport:
- [[#description][Description]]
- [[#module-flags][Module Flags]]
- [[#prerequisites][Prerequisites]]
- [[#configuration][Configuration]]
- [[#a-custom-banner][A custom banner]]
- [[#adding-text-to-the-dashboard][Adding text to the dashboard]]
- [[#customizing-faces][Customizing Faces]]
* Description
This module gives Doom Emacs a dashboard buffer.
This module adds a minimalistic, Atom-inspired dashboard to Emacs.
It is loosely inspired by Atom's dashboard.
Besides eye candy, the dashboard serves two other purposes:
1. To improve Doom's startup times (the dashboard is lighter than the scratch
buffer in many cases).
2. And to preserve the "last open directory" you were in. Occasionally, I kill
the last buffer in my project and I end up who-knows-where (in the working
directory of another buffer/project). It can take some work to find my way
back to where I was. Not with the Dashboard.
Since the dashboard cannot be killed, and it remembers the working directory
of the last open buffer, ~M-x find-file~ will work from the directory I
expect.
** Module Flags
This module provides no flags.
* Prerequisites
This module only requires that ~all-the-icons~'s icon fonts are installed. Use ~M-x all-the-icons-install-fonts~ to do so.
This module only requires that ~all-the-icons~'s icon fonts are installed.
It should've been installed when you first installed Doom, but ~M-x
all-the-icons-install-fonts~ will install them again.
* Configuration
** A custom banner
To use a custom image as your banner, change ~fancy-splash-image~:
#+BEGIN_SRC elisp
(setq fancy-splash-image "~/my/banners/image.png")
#+END_SRC
#+begin_quote
Doom will fall back to its ASCII banner in Terminal Emacs. To replace the ASCII
banner, replace the ~doom-dashboard-widget-banner~ function in
~+doom-dashboard-functions~ with a function that inserts your new banner into
the current file.
#+end_quote
** Adding text to the dashboard
Doom's dashboard iterates over ~+doom-dashboard-functions~ when it is told to
redraw. Add your own functions to operate on the buffer and potentially add
whatever you like to Doom's splash screen.
#+begin_quote
Keep in mind that inserting text from expensive sources, e.g. your org agenda,
will negate most of Doom's startup benefits.
#+end_quote
** Customizing Faces
Doom's dashboard defaults to inheriting faces set by the current theme. If you wish
to customize it independently of the theme (or just inherit a different color
from the theme) you can make use of ~custom-set-faces!~ or ~custom-theme-set-faces!~
#+BEGIN_SRC elisp
(custom-set-faces!
'(doom-dashboard-banner :foreground "red" :background "#000000" :weight bold)
'(doom-dashboard-footer :inherit font-lock-constant-face)
'(doom-dashboard-footer-icon :inherit all-the-icons-red)
'(doom-dashboard-loaded :inherit font-lock-warning-face)
'(doom-dashboard-menu-desc :inherit font-lock-string-face)
'(doom-dashboard-menu-title :inherit font-lock-function-name-face))
#+END_SRC
or for a per-theme setting
#+BEGIN_SRC elisp
(custom-theme-set-faces! 'doom-tomorrow-night
'(doom-dashboard-banner :foreground "red" :background "#000000" :weight bold)
'(doom-dashboard-footer :inherit font-lock-constant-face)
'(doom-dashboard-footer-icon :inherit all-the-icons-red)
'(doom-dashboard-loaded :inherit font-lock-warning-face)
'(doom-dashboard-menu-desc :inherit font-lock-string-face)
'(doom-dashboard-menu-title :inherit font-lock-function-name-face))
#+END_SRC

View file

@ -19,7 +19,7 @@ relative to `+doom-dashboard-banner-dir'. If nil, always use the ASCII banner.")
(defvar +doom-dashboard-banner-dir (concat (dir!) "/banners/")
"Where to look for `+doom-dashboard-banner-file'.")
(defvar +doom-dashboard-banner-padding '(4 . 4)
(defvar +doom-dashboard-banner-padding '(0 . 4)
"Number of newlines to pad the banner with, above and below, respectively.")
(defvar +doom-dashboard-inhibit-refresh nil
@ -43,33 +43,33 @@ Possible values:
(defvar +doom-dashboard-menu-sections
'(("Reload last session"
:icon (all-the-icons-octicon "history" :face 'font-lock-keyword-face)
:icon (all-the-icons-octicon "history" :face 'doom-dashboard-menu-title)
:when (cond ((require 'persp-mode nil t)
(file-exists-p (expand-file-name persp-auto-save-fname persp-save-dir)))
((require 'desktop nil t)
(file-exists-p (desktop-full-file-name))))
:face (:inherit (font-lock-keyword-face bold))
:face (:inherit (doom-dashboard-menu-title bold))
:action doom/quickload-session)
("Open org-agenda"
:icon (all-the-icons-octicon "calendar" :face 'font-lock-keyword-face)
:icon (all-the-icons-octicon "calendar" :face 'doom-dashboard-menu-title)
:when (fboundp 'org-agenda)
:action org-agenda)
("Recently opened files"
:icon (all-the-icons-octicon "file-text" :face 'font-lock-keyword-face)
:icon (all-the-icons-octicon "file-text" :face 'doom-dashboard-menu-title)
:action recentf-open-files)
("Open project"
:icon (all-the-icons-octicon "briefcase" :face 'font-lock-keyword-face)
:icon (all-the-icons-octicon "briefcase" :face 'doom-dashboard-menu-title)
:action projectile-switch-project)
("Jump to bookmark"
:icon (all-the-icons-octicon "bookmark" :face 'font-lock-keyword-face)
:icon (all-the-icons-octicon "bookmark" :face 'doom-dashboard-menu-title)
:action bookmark-jump)
("Open private configuration"
:icon (all-the-icons-octicon "tools" :face 'font-lock-keyword-face)
:icon (all-the-icons-octicon "tools" :face 'doom-dashboard-menu-title)
:when (file-directory-p doom-private-dir)
:action doom/open-private-config)
("Search Documentation"
:icon (all-the-icons-octicon "book" :face 'font-lock-keyword-face)
:action doom/help-search))
("Open documentation"
:icon (all-the-icons-octicon "book" :face 'doom-dashboard-menu-title)
:action doom/help))
"An alist of menu buttons used by `doom-dashboard-widget-shortmenu'. Each
element is a cons cell (LABEL . PLIST). LABEL is a string to display after the
icon and before the key string.
@ -125,10 +125,44 @@ PLIST can have the following properties:
;; `persp-mode' integration: update `default-directory' when switching perspectives
(add-hook 'persp-created-functions #'+doom-dashboard--persp-record-project-h)
(add-hook 'persp-activated-functions #'+doom-dashboard--persp-detect-project-h)
;; HACK Fix #2219 where, in GUI daemon frames, the dashboard loses center
;; alignment after switching (or killing) workspaces.
(when (daemonp)
(add-hook 'persp-activated-functions #'+doom-dashboard-reload-maybe-h))
(add-hook 'persp-before-switch-functions #'+doom-dashboard--persp-record-project-h)))
(add-hook 'doom-init-ui-hook #'+doom-dashboard-init-h)
;;
;;; Faces
(defgroup doom-dashboard nil
"Manage how doom-dashboard is coloured and themed."
:prefix "doom-dashboard"
:group 'doom-themes)
(defface doom-dashboard-banner '((t (:inherit font-lock-comment-face)))
"Face used for the DOOM banner on the dashboard"
:group 'doom-dashboard)
(defface doom-dashboard-footer '((t (:inherit font-lock-keyword-face)))
"Face used for the footer on the dashboard"
:group 'doom-dashboard)
(defface doom-dashboard-footer-icon '((t (:inherit all-the-icons-green)))
"Face used for the icon of the footer on the dashboard"
:group 'doom-dashboard)
(defface doom-dashboard-loaded '((t (:inherit font-lock-comment-face)))
"Face used for the loaded packages benchmark"
:group 'doom-dashboard)
(defface doom-dashboard-menu-desc '((t (:inherit font-lock-constant-face)))
"Face used for the key description of menu widgets on the dashboard"
:group 'doom-dashboard)
(defface doom-dashboard-menu-title '((t (:inherit font-lock-keyword-face)))
"Face used for the title of menu widgets on the dashboard"
:group 'doom-dashboard)
;;
;;; Major mode
@ -202,7 +236,7 @@ PLIST can have the following properties:
(goto-char (point-min))
(forward-button 1))))
(defun +doom-dashboard-reload-maybe-h ()
(defun +doom-dashboard-reload-maybe-h (&rest _)
"Reload the dashboard or its state.
If this isn't a dashboard buffer, move along, but record its `default-directory'
@ -245,10 +279,10 @@ whose dimensions may not be fully initialized by the time this is run."
(save-excursion (skip-chars-forward "\n")
(point)))
(insert (make-string
(max 0 (- (/ (window-height (get-buffer-window)) 2)
(round (/ (+ (count-lines (point-min) (point-max))
(car +doom-dashboard-banner-padding))
2))))
(+ (max 0 (- (/ (window-height (get-buffer-window)) 2)
(round (/ (count-lines (point-min) (point-max))
2))))
(car +doom-dashboard-banner-padding))
?\n)))))))))
(defun +doom-dashboard--persp-detect-project-h (&rest _)
@ -348,7 +382,7 @@ controlled by `+doom-dashboard-pwd-policy'."
(let ((point (point)))
(mapc (lambda (line)
(insert (propertize (+doom-dashboard--center +doom-dashboard--width line)
'face 'font-lock-comment-face) " ")
'face 'doom-dashboard-banner) " ")
(insert "\n"))
'("================= =============== =============== ======== ========"
"\\\\ . . . . . . .\\\\ //. . . . . . .\\\\ //. . . . . . .\\\\ \\\\. . .\\\\// . . //"
@ -393,7 +427,7 @@ controlled by `+doom-dashboard-pwd-policy'."
(+doom-dashboard--center
+doom-dashboard--width
(doom-display-benchmark-h 'return))
'face 'font-lock-comment-face)
'face 'doom-dashboard-loaded)
"\n"))
(defun doom-dashboard-widget-shortmenu ()
@ -418,11 +452,11 @@ controlled by `+doom-dashboard-pwd-policy'."
`(lambda (_)
(call-interactively (or (command-remapping #',action)
#',action)))
'face (or face 'font-lock-keyword-face)
'face (or face 'doom-dashboard-menu-title)
'follow-link t
'help-echo
(format "%s (%s)" label
(propertize (symbol-name action) 'face 'font-lock-constant-face)))
(propertize (symbol-name action) 'face 'doom-dashboard-menu-desc)))
(format "%-37s" (buffer-string)))
;; Lookup command keys dynamically
(or (when-let (key (where-is-internal action nil t))
@ -434,7 +468,7 @@ controlled by `+doom-dashboard-pwd-policy'."
(upcase (if (< (length str) 3)
str
(substring str 0 3))))))
(propertize (buffer-string) 'face 'font-lock-constant-face)))
(propertize (buffer-string) 'face 'doom-dashboard-menu-desc)))
""))))
(if (display-graphic-p)
"\n\n"
@ -446,8 +480,8 @@ controlled by `+doom-dashboard-pwd-policy'."
(+doom-dashboard--center
(- +doom-dashboard--width 2)
(with-temp-buffer
(insert-text-button (or (all-the-icons-octicon "octoface" :face 'all-the-icons-green :height 1.3 :v-adjust -0.15)
(propertize "github" 'face 'font-lock-keyword-face))
(insert-text-button (or (all-the-icons-octicon "octoface" :face 'doom-dashboard-footer-icon :height 1.3 :v-adjust -0.15)
(propertize "github" 'face 'doom-dashboard-footer))
'action (lambda (_) (browse-url "https://github.com/hlissner/doom-emacs"))
'follow-link t
'help-echo "Open Doom Emacs github page")

View file

@ -6,26 +6,32 @@
* Table of Contents :TOC_3:noexport:
- [[#description][Description]]
- [[#module-flags][Module Flags]]
- [[#plugins][Plugins]]
- [[#prerequisites][Prerequisites]]
- [[#configuration][Configuration]]
- [[#changing-theme][Changing theme]]
- [[#changing-fonts][Changing fonts]]
- [[#troubleshooting][Troubleshooting]]
- [[#strange-font-symbols][Strange font symbols]]
- [[#ugly-background-colors-in-tty-emacs-for-daemon-users][Ugly background colors in tty Emacs for daemon users]]
* Description
This module modifies Emacs' user interface.
This module gives Doom its signature look: powered by the =doom-one= theme
(inspired by Atom's One Dark theme) and =solaire-mode=.
Doom's look is loosely inspired by Atom's One Dark theme, and is largely contained in the] plugin.
+ A colorscheme inspired by Atom's One Dark theme (now available in a separate plugin: [[https://github.com/hlissner/emacs-doom-theme/][doom-themes]])
+ A colorscheme inspired by Atom's One Dark theme (now available in a separate
plugin: [[https://github.com/hlissner/emacs-doom-theme/][doom-themes]])
+ A custom folded-region indicator for ~hideshow~
+ "Thin bar" fringe bitmaps for ~git-gutter-fringe~
+ File-visiting buffers are slightly brighter (powered by solaire-mode)
+ File-visiting buffers are slightly brighter (thanks to solaire-mode)
** Module Flags
This module provides no flags.
** Plugins
+ [[https://github.com/hlissner/emacs-doom-themes][doom-themes]]
+ [[https://github.com/hlissner/emacs-solaire-mode][solaire-mode]]
* Prerequisites
This module has no prereqisites.
@ -64,4 +70,24 @@ core/core-ui.el has four relevant variables:
* Troubleshooting
** Strange font symbols
If you're seeing strange unicode symbols, this is likely because you don't have ~all-the-icons~'s font icon installed. You can install them with ~M-x all-the-icons-install-fonts~.
If you're seeing strange unicode symbols, this is likely because you don't have
~all-the-icons~'s font icon installed. You can install them with ~M-x
all-the-icons-install-fonts~.
** Ugly background colors in tty Emacs for daemon users
=solaire-mode= is an aesthetic plugin that makes file-visiting buffers brighter
than the rest of the Emacs' frame (to visually differentiate temporary windows
or sidebars from editing windows). This looks great in GUI Emacs, but can look
questionable in the terminal.
It disables itself if you start tty Emacs with ~emacs -nw~, but if you create a
tty frame from a daemon (which solaire-mode cannot anticipate), you'll get an
ugly background instead.
If you only use Emacs in the terminal, your best bet is to disable the
solaire-mode package:
#+BEGIN_SRC elisp
;; in ~/.doom.d/packages.el
(package! solaire-mode :disable t)
#+END_SRC

View file

@ -1,20 +1,39 @@
;;; ui/doom/config.el -*- lexical-binding: t; -*-
(defvar +doom-solaire-themes
'((doom-city-lights . t)
'((doom-acario-dark . t)
(doom-acario-light . t)
(doom-challenger-deep . t)
(doom-city-lights . t)
(doom-dark+ . t)
(doom-dracula . t)
(doom-molokai)
(doom-fairy-floss . t)
(doom-gruvbox . t)
(doom-horizon . t)
(doom-laserwave . t)
(doom-losvkem . t)
(doom-manegarm . t)
(doom-material . t)
(doom-molokai . t)
(doom-moonlight . t)
(doom-nord . t)
(doom-nord-light . t)
(doom-nova)
(doom-nova . t)
(doom-oceanic-next . t)
(doom-one . t)
(doom-one-light . t)
(doom-outrun-electric . t)
(doom-opera . t)
(doom-palenight . t)
(doom-peacock . t)
(doom-snazzy . t)
(doom-solarized-dark . t)
(doom-solarized-light)
(doom-spacegrey)
(doom-vibrant)
(doom-tomorrow-night))
(doom-sourcerer . t)
(doom-spacegrey . t)
(doom-tomorrow-day . t)
(doom-tomorrow-night . t)
(doom-vibrant . t))
"An alist of themes that support `solaire-mode'. If CDR is t, then
`solaire-mode-swap-bg' will be used automatically, when the theme is loaded.")
@ -22,7 +41,6 @@
;;
;;; Packages
;; <https://github.com/hlissner/emacs-doom-theme>
(use-package! doom-themes
:defer t
:init
@ -42,6 +60,7 @@
(use-package! solaire-mode
:when (or (daemonp) (display-graphic-p))
:defer t
:init
(add-hook! 'doom-load-theme-hook :append

View file

@ -1,6 +1,5 @@
;; -*- no-byte-compile: t; -*-
;;; ui/doom/packages.el
(package! doom-themes)
(package! solaire-mode)
(package! doom-themes :pin "ecffdf82ff")
(package! solaire-mode :pin "4ac324ccb0")

View file

@ -1,4 +1,4 @@
;; -*- no-byte-compile: t; -*-
;;; ui/fill-column/packages.el
(package! hl-fill-column)
(package! hl-fill-column :pin "612441e697")

View file

@ -5,12 +5,12 @@
:config
(setq hl-todo-highlight-punctuation ":"
hl-todo-keyword-faces
`(("TODO" . ,(face-foreground 'warning))
("FIXME" . ,(face-foreground 'error))
("HACK" . ,(face-foreground 'font-lock-constant-face))
("REVIEW" . ,(face-foreground 'font-lock-keyword-face))
("NOTE" . ,(face-foreground 'success))
("DEPRECATED" . ,(face-foreground 'font-lock-doc-face))))
`(("TODO" warning bold)
("FIXME" error bold)
("HACK" font-lock-constant-face bold)
("REVIEW" font-lock-keyword-face bold)
("NOTE" success bold)
("DEPRECATED" font-lock-doc-face bold)))
;; Use a more primitive todo-keyword detection method in major modes that
;; don't use/have a valid syntax table entry for comments.

View file

@ -1,4 +1,4 @@
;; -*- no-byte-compile: t; -*-
;;; ui/hl-todo/packages.el
(package! hl-todo)
(package! hl-todo :pin "5d2ea49f83")

View file

@ -1,7 +1,7 @@
;;; ui/hydra/autoload/windows.el -*- lexical-binding: t; -*-
;;;###autoload (autoload '+hydra/text-zoom/body "ui/hydra/autoload/windows" nil t)
(defhydra +hydra/text-zoom (:hint t :color red)
(defhydra +hydra/text-zoom (:hint nil :color red)
"
Text zoom: _j_:zoom in, _k_:zoom out, _0_:reset
"

View file

@ -1,4 +1,4 @@
;; -*- no-byte-compile: t; -*-
;;; ui/hydra/packages.el
(package! hydra)
(package! hydra :pin "e3beffdd80")

View file

@ -7,7 +7,7 @@
:config
(add-hook 'focus-in-hook #'highlight-indent-guides-auto-set-faces)
;; `highlight-indent-guides' breaks in these modes
(add-hook! '(visual-line-mode-hook org-indent-mode-hook)
(add-hook! 'org-indent-mode-hook
(defun +indent-guides-disable-maybe-h ()
(when highlight-indent-guides-mode
(highlight-indent-guides-mode -1)))))

View file

@ -1,4 +1,4 @@
;; -*- no-byte-compile: t; -*-
;;; ui/indent-guides/packages.el
(package! highlight-indent-guides)
(package! highlight-indent-guides :pin "0b10f38c54")

View file

@ -0,0 +1,555 @@
;;; ui/modeline/+default.el -*- lexical-binding: t; -*-
;; This is a slimmed down version of `doom-modeline' that manipulates
;; `mode-line-format' directly. Its purpose is to be truer to the original goal
;; of Doom's modeline: to be more performant and minimalistic alternative to
;; other modeline packages and to be abstraction-light. Too much abstraction is
;; too much magic.
;;
;; Warning: this is still a WIP!
(defun +modeline--set-var-and-refresh-bars-fn (&optional symbol value)
(when symbol
(set-default symbol value))
(when doom-init-time
(+modeline-refresh-bars-h)))
;;
;;; Variables
(defcustom +modeline-height 31
"The height of the modeline.
This is enforced by the xpm bitmap bar in `+modeline-bar'. Without it (and in
the terminal), this variable does nothing.
Use `setq!' to adjust this variable live, as it will trigger an refresh of the
bars in the modeline. `setq' will not."
:type 'integer
:set #'+modeline--set-var-and-refresh-bars-fn)
(defcustom +modeline-bar-width 3
"The width of the bar in the modeline.
If nil, the bar will be made transparent and 1 pixel wide, as to be invisible,
but without sacrificing its ability to enforce `+modeline-height'.
Use `setq!' to adjust this variable live, as it will trigger an refresh of the
bars in the modeline. `setq' will not."
:type 'integer
:set #'+modeline--set-var-and-refresh-bars-fn)
(defvar +modeline-format-alist ()
"An alist of modeline formats defined with `def-modeline!'.
Each entry's CAR is the name and CDR is a cons cell whose CAR is the left-hand
side of the modeline, and whose CDR is the right-hand side.")
;;
;;; Faces
(defface +modeline-bar-active '((t (:inherit highlight)))
"Face used for left-most bar on the mode-line of an active window.")
(defface +modeline-bar-inactive '((t (:inherit mode-line-inactive)))
"Face used for left-most bar on the mode-line of an inactive window.")
(defface +modeline-highlight
'((t (:inherit mode-line-highlight)))
"Face used for highlighted modeline panels (like search counts).")
(defface +modeline-alternate-highlight
'((t (:inherit mode-line-highlight)))
"Alternative face used for highlighted modeline panels (like search counts).")
;;
;;; Helpers
;;; `active'
(defvar +modeline--active-window (selected-window))
(defun +modeline-active ()
"Return non-nil if the selected window has an active modeline."
(eq (selected-window) +modeline--active-window))
(add-hook! 'pre-redisplay-functions
(defun +modeline-set-selected-window-h (&rest _)
"Track the active modeline's window in `+modeline--active-window'."
(let ((win (selected-window)))
(unless (minibuffer-window-active-p win)
(setq +modeline--active-window (frame-selected-window))))))
(defun +modeline--make-xpm (color width height)
"Create an XPM bitmap via COLOR, WIDTH and HEIGHT. Inspired by `powerline''s `pl/+modeline--make-xpm'."
(propertize
" " 'display
(let ((data (make-list height (make-list width 1)))
(color (or color "None")))
(ignore-errors
(create-image
(concat
(format "/* XPM */\nstatic char * percent[] = {\n\"%i %i 2 1\",\n\". c %s\",\n\" c %s\","
(length (car data))
(length data)
color
color)
(apply #'concat
(cl-loop with idx = 0
with len = (length data)
for dl in data
do (cl-incf idx)
collect
(concat "\""
(cl-loop for d in dl
if (= d 0) collect (string-to-char " ")
else collect (string-to-char "."))
(if (eq idx len) "\"};" "\",\n")))))
'xpm t :ascent 'center)))))
(defun +modeline-format-icon (icon label &optional face help-echo voffset)
(propertize (concat (all-the-icons-material
icon
:face face
:height 1.1
:v-adjust (or voffset -0.225))
(propertize label 'face face))
'help-echo help-echo))
(defun set-modeline! (name &optional default)
"Set the modeline to NAME.
If DEFAULT is non-nil, apply to all future buffers. Modelines are defined with
`def-modeline!'."
(if-let (format (assq name +modeline-format-alist))
(cl-destructuring-bind (lhs . rhs) (cdr format)
(if default
(setq-default +modeline-format-left lhs
+modeline-format-right rhs)
(setq +modeline-format-left lhs
+modeline-format-right rhs)))
(error "Could not find %S modeline format" name)))
(defun set-modeline-hook! (hooks name)
"Set the modeline to NAME on HOOKS.
See `def-modeline!' on how modelines are defined."
(let ((fn (intern (format "+modeline-set-%s-format-h" name))))
(dolist (hook (doom-enlist hooks))
(when after-init-time
(dolist (name (mapcar #'car +modeline-format-alist))
(remove-hook hook (intern (format "+modeline-set-%s-format-h" name)))))
(add-hook hook fn))))
(defun def-modeline! (name lhs rhs)
"Define a modeline format by NAME.
LHS and RHS are the formats representing the left and right hand side of the
mode-line, respectively. See the variable `format-mode-line' for details on what
LHS and RHS will accept."
(setf (alist-get name +modeline-format-alist)
(cons lhs rhs))
(fset (intern (format "+modeline-set-%s-format-h" name))
(lambda (&rest _) (set-modeline! name))))
(defmacro def-modeline-var! (name body &optional docstring &rest plist)
"TODO"
(unless (stringp docstring)
(push docstring plist)
(setq docstring nil))
`(progn
(,(if (plist-get plist :local) 'defvar-local 'defvar)
,name ,body ,docstring)
(put ',name 'risky-local-variable t)))
;;
;;; Segments
(def-modeline-var! +modeline-format-left nil
"The left-hand side of the modeline."
:local t)
(def-modeline-var! +modeline-format-right nil
"The right-hand side of the modeline."
:local t)
;;; `+modeline-bar'
(progn
(def-modeline-var! +modeline-bar "")
(def-modeline-var! +modeline-inactive-bar "")
(add-hook! '(doom-init-ui-hook doom-load-theme-hook) :append
(defun +modeline-refresh-bars-h ()
(let ((width (or +modeline-bar-width 1))
(height (max +modeline-height 0)))
(setq +modeline-bar
(+modeline--make-xpm
(and +modeline-bar-width
(face-background '+modeline-bar-active nil t))
width height)
+modeline-inactive-bar
(+modeline--make-xpm
(and +modeline-bar-width
(face-background '+modeline-bar-inactive nil t))
width height)))))
(add-hook! 'doom-change-font-size-hook
(defun +modeline-adjust-height-h ()
(defvar +modeline--old-height +modeline-height)
(let ((default-height +modeline--old-height)
(scale (or (frame-parameter nil 'font-scale) 0)))
(setq +modeline-height
(if (> scale 0)
(+ default-height (* (or (frame-parameter nil 'font-scale) 1)
doom-font-increment))
default-height))
(when doom-init-time
(+modeline-refresh-bars-h))))))
;;; `+modeline-matches'
(progn
(use-package! anzu
:after-call isearch-mode
:config
;; anzu and evil-anzu expose current/total state that can be displayed in the
;; mode-line.
(defadvice! +modeline-fix-anzu-count-a (positions here)
"Calulate anzu counts via POSITIONS and HERE."
:override #'anzu--where-is-here
(cl-loop for (start . end) in positions
collect t into before
when (and (>= here start) (<= here end))
return (length before)
finally return 0))
(setq anzu-cons-mode-line-p nil) ; manage modeline segment ourselves
;; Ensure anzu state is cleared when searches & iedit are done
(add-hook 'isearch-mode-end-hook #'anzu--reset-status 'append)
(add-hook 'iedit-mode-end-hook #'anzu--reset-status)
(advice-add #'evil-force-normal-state :before #'anzu--reset-status)
;; Fix matches segment mirroring across all buffers
(mapc #'make-variable-buffer-local
'(anzu--total-matched anzu--current-position anzu--state
anzu--cached-count anzu--cached-positions anzu--last-command
anzu--last-isearch-string anzu--overflow-p)))
(use-package! evil-anzu
:when (featurep! :editor evil)
:after-call (evil-ex-start-search evil-ex-start-word-search evil-ex-search-activate-highlight))
(defun +modeline--anzu ()
"Show the match index and total number thereof.
Requires `anzu', also `evil-anzu' if using `evil-mode' for compatibility with
`evil-search'."
(when (and (bound-and-true-p anzu--state)
(not (bound-and-true-p iedit-mode)))
(propertize
(let ((here anzu--current-position)
(total anzu--total-matched))
(cond ((eq anzu--state 'replace-query)
(format " %d replace " anzu--cached-count))
((eq anzu--state 'replace)
(format " %d/%d " here total))
(anzu--overflow-p
(format " %s+ " total))
(t
(format " %s/%d " here total))))
'face (if (+modeline-active) '+modeline-highlight))))
(defun +modeline--evil-substitute ()
"Show number of matches for evil-ex substitutions and highlights in real time."
(when (and (bound-and-true-p evil-local-mode)
(or (assq 'evil-ex-substitute evil-ex-active-highlights-alist)
(assq 'evil-ex-global-match evil-ex-active-highlights-alist)
(assq 'evil-ex-buffer-match evil-ex-active-highlights-alist)))
(propertize
(let ((range (if evil-ex-range
(cons (car evil-ex-range) (cadr evil-ex-range))
(cons (line-beginning-position) (line-end-position))))
(pattern (car-safe (evil-delimited-arguments evil-ex-argument 2))))
(if pattern
(format " %s matches " (how-many pattern (car range) (cdr range)))
" - "))
'face (if (+modeline-active) '+modeline-highlight))))
(defun +modeline--multiple-cursors ()
"Show the number of multiple cursors."
(when (bound-and-true-p evil-mc-cursor-list)
(let ((count (length evil-mc-cursor-list)))
(when (> count 0)
(let ((face (cond ((not (+modeline-active)) 'mode-line-inactive)
(evil-mc-frozen '+modeline-highlight)
('+modeline-alternate-highlight))))
(concat (propertize " " 'face face)
(all-the-icons-faicon "i-cursor" :face face :v-adjust -0.0575)
(propertize " " 'face `(:inherit (variable-pitch ,face)))
(propertize (format "%d " count)
'face face)))))))
(defun +modeline--overlay< (a b)
"Sort overlay A and B."
(< (overlay-start a) (overlay-start b)))
(defun +modeline--iedit ()
"Show the number of iedit regions matches + what match you're on."
(when (and (bound-and-true-p iedit-mode)
(bound-and-true-p iedit-occurrences-overlays))
(propertize
(let ((this-oc (or (let ((inhibit-message t))
(iedit-find-current-occurrence-overlay))
(save-excursion
(iedit-prev-occurrence)
(iedit-find-current-occurrence-overlay))))
(length (length iedit-occurrences-overlays)))
(format " %s/%d "
(if this-oc
(- length
(length (memq this-oc (sort (append iedit-occurrences-overlays nil)
#'+modeline--overlay<)))
-1)
"-")
length))
'face (if (+modeline-active) '+modeline-highlight))))
(defun +modeline--macro-recording ()
"Display current Emacs or evil macro being recorded."
(when (and (+modeline-active)
(or defining-kbd-macro
executing-kbd-macro))
(let ((sep (propertize " " 'face '+modeline-highlight)))
(concat sep
(propertize (if (bound-and-true-p evil-this-macro)
(char-to-string evil-this-macro)
"Macro")
'face '+modeline-highlight)
sep
(all-the-icons-octicon "triangle-right"
:face '+modeline-highlight
:v-adjust -0.05)
sep))))
(def-modeline-var! +modeline-matches
'(:eval
(let ((meta (concat (+modeline--macro-recording)
(+modeline--anzu)
(+modeline--evil-substitute)
(+modeline--iedit)
(+modeline--multiple-cursors))))
(or (and (not (equal meta "")) meta)
" %I ")))))
;;; `+modeline-modes'
(def-modeline-var! +modeline-modes ; remove minor modes
'(""
(:propertize mode-name
face bold
mouse-face +modeline-highlight)
mode-line-process
"%n"
" "))
;;; `+modeline-buffer-identification'
(def-modeline-var! +modeline-buffer-identification ; slightly more informative buffer id
'((:eval
(propertize
(let ((buffer-file-name (buffer-file-name (buffer-base-buffer))))
(or (when buffer-file-name
(if-let (project (doom-project-root buffer-file-name))
(let ((filename (or buffer-file-truename (file-truename buffer-file-name))))
(file-relative-name filename (concat project "..")))))
"%b"))
'face (cond ((buffer-modified-p)
'(error bold mode-line-buffer-id))
((+modeline-active)
'mode-line-buffer-id))
'help-echo buffer-file-name))
(buffer-read-only (:propertize " RO" face warning))))
;;; `+modeline-position'
(def-modeline-var! +modeline-position '(" %l:%C %p "))
;;; `+modeline-checker'
(progn
(def-modeline-var! +modeline-checker nil
"Displays color-coded error status & icon for the current buffer."
:local t)
(add-hook! '(flycheck-status-changed-functions
flycheck-mode-hook)
(defun +modeline-checker-update (&optional status)
"Update flycheck text via STATUS."
(setq +modeline-checker
(pcase status
(`finished
(if flycheck-current-errors
(let-alist (flycheck-count-errors flycheck-current-errors)
(let ((error (or .error 0))
(warning (or .warning 0))
(info (or .info 0)))
(+modeline-format-icon "do_not_disturb_alt"
(number-to-string (+ error warning info))
(cond ((> error 0) 'error)
((> warning 0) 'warning)
('success))
(format "Errors: %d, Warnings: %d, Debug: %d"
error
warning
info))))
(+modeline-format-icon "check" "" 'success)))
(`running (+modeline-format-icon "access_time" "*" 'font-lock-comment-face "Running..."))
(`errored (+modeline-format-icon "sim_card_alert" "!" 'error "Errored!"))
(`interrupted (+modeline-format-icon "pause" "!" 'font-lock-comment-face "Interrupted"))
(`suspicious (+modeline-format-icon "priority_high" "!" 'error "Suspicious")))))))
;;; `+modeline-selection-info'
(progn
(defsubst +modeline--column (pos)
"Get the column of the position `POS'."
(save-excursion (goto-char pos)
(current-column)))
(def-modeline-var! +modeline-selection-info
'(:eval
(when (or mark-active
(and (bound-and-true-p evil-local-mode)
(eq evil-state 'visual)))
(cl-destructuring-bind (beg . end)
(if (boundp 'evil-local-mode)
(cons evil-visual-beginning evil-visual-end)
(cons (region-beginning) (region-end)))
(propertize
(let ((lines (count-lines beg (min end (point-max)))))
(concat " "
(cond ((or (bound-and-true-p rectangle-mark-mode)
(and (bound-and-true-p evil-visual-selection)
(eq 'block evil-visual-selection)))
(let ((cols (abs (- (+modeline--column end)
(+modeline--column beg)))))
(format "%dx%dB" lines cols)))
((and (bound-and-true-p evil-visual-selection)
(eq evil-visual-selection 'line))
(format "%dL" lines))
((> lines 1)
(format "%dC %dL" (- end beg) lines))
((format "%dC" (- end beg))))
(when (derived-mode-p 'text-mode)
(format " %dW" (count-words beg end)))
" "))
'face (if (+modeline-active) 'success)))))
"Information about the current selection, such as how many characters and
lines are selected, or the NxM dimensions of a block selection.")
(defun +modeline-add-selection-segment-h ()
(add-to-list '+modeline-format-left '+modeline-selection-info 'append))
(defun +modeline-remove-selection-segment-h ()
(delq! '+modeline-selection-info +modeline-format-left))
(if (featurep 'evil)
(progn
(add-hook 'evil-visual-state-entry-hook #'+modeline-add-selection-segment-h)
(add-hook 'evil-visual-state-exit-hook #'+modeline-remove-selection-segment-h))
(add-hook 'activate-mark-hook #'+modeline-add-selection-segment-h)
(add-hook 'deactivate-mark-hook #'+modeline-remove-selection-segment-h)))
;;; `+modeline-encoding'
(def-modeline-var! +modeline-encoding
'(:eval
(concat (coding-system-eol-type-mnemonic buffer-file-coding-system)
" "
(let ((sys (coding-system-plist buffer-file-coding-system)))
(if (memq (plist-get sys :category)
'(coding-category-undecided coding-category-utf-8))
"UTF-8"
(upcase (symbol-name (plist-get sys :name))))))))
;; Clearer mnemonic labels for EOL styles
(setq eol-mnemonic-dos "CRLF"
eol-mnemonic-mac "CR"
eol-mnemonic-unix "LF"
eol-mnemonic-undecided "??")
;;
;;; Default modeline
(def-modeline! :main
'(""
+modeline-matches
" "
+modeline-buffer-identification
+modeline-position)
`(""
mode-line-misc-info
+modeline-modes
(vc-mode (" "
,(all-the-icons-octicon "git-branch" :v-adjust 0.0)
vc-mode " "))
" "
+modeline-encoding
" "
(+modeline-checker ("" +modeline-checker " "))))
(def-modeline! 'project
`(" "
,(all-the-icons-octicon
"file-directory"
:face 'bold
:v-adjust -0.05
:height 1.25)
(:propertize (" " (:eval (abbreviate-file-name default-directory)))
face bold))
'("" +modeline-modes))
(def-modeline! 'special
'("" +modeline-matches
" " +modeline-buffer-identification)
'("" +modeline-modes))
;; TODO (def-modeline! pdf ...)
;; TODO (def-modeline! helm ...)
;;
;;; Bootstrap
(size-indication-mode +1) ; filesize in modeline
(setq-default
mode-line-format
'(""
+modeline-bar
+modeline-format-left
(:eval
(propertize
" "
'display
`((space :align-to (- (+ right right-fringe right-margin)
,(string-width
(format-mode-line '("" +modeline-format-right))))))))
+modeline-format-right))
(with-current-buffer "*Messages*"
(setq mode-line-format (default-value 'mode-line-format)))
;; Other modes
(set-modeline! :main 'default)
(set-modeline-hook! '+doom-dashboard-mode-hook 'project)
;; (set-modeline-hook! 'pdf-tools-enabled-hook 'pdf)
(set-modeline-hook! '(special-mode-hook
image-mode-hook
circe-mode-hook)
'special)
(add-hook! 'magit-mode-hook
(defun +modeline-init-project-or-hide-h ()
(if (eq major-mode 'magit-status-mode)
(set-modeline! 'project)
(hide-mode-line-mode +1))))

View file

@ -30,7 +30,8 @@ This module provides an Atom-inspired, minimalistic modeline for Doom Emacs,
powered by [[https://github.com/seagle0128/doom-modeline][the doom-modeline package]] (where you can find screenshots).
** Module Flags
This module provides no flags.
+ =+light= Enables a lighter, less featureful version of the modeline that does
not depend on ~doom-modeline~, which has performances issues in some cases.
** Plugins
+ [[https://github.com/seagle0128/doom-modeline][doom-modeline]]

View file

@ -21,14 +21,10 @@ Meant for `doom-change-font-size-hook'."
(setq +modeline--old-bar-height doom-modeline-height))
(let ((default-height +modeline--old-bar-height)
(scale (or (frame-parameter nil 'font-scale) 0)))
(if (> scale 0)
(let* ((font-size (string-to-number
(aref (doom--font-name (frame-parameter nil 'font)
(selected-frame))
xlfd-regexp-pixelsize-subnum)))
(scale (frame-parameter nil 'font-scale)))
(setq doom-modeline-height (+ default-height (* scale doom-font-increment))))
(setq doom-modeline-height default-height))))
(setq doom-modeline-height
(if (> scale 0)
(+ default-height (* scale doom-font-increment))
default-height))))
;;;###autoload
(defun +modeline-update-env-in-all-windows-h (&rest _)

View file

@ -1,6 +1,20 @@
;;; ui/modeline/config.el -*- lexical-binding: t; -*-
(when (featurep! +light)
(load! "+light"))
(defvar +modeline--redisplayed-p nil)
(defadvice! modeline-recalculate-height-a (&optional _force &rest _ignored)
"Ensure that window resizing functions take modeline height into account."
:before '(fit-window-to-buffer resize-temp-buffer-window)
(unless +modeline--redisplayed-p
(setq-local +modeline--redisplayed-p t)
(redisplay t)))
(use-package! doom-modeline
:unless (featurep! +light)
:hook (after-init . doom-modeline-mode)
:init
(unless after-init-time
@ -37,17 +51,6 @@
(add-hook '+doom-dashboard-mode-hook #'doom-modeline-set-project-modeline)
(when (or (featurep! :ui pretty-code +fira)
(featurep! :ui pretty-code +iosevka))
;; Fix #1216 and seagle0128/doom-modeline#69: wrong icon displayed for
;; 'save' icon in modeline.
(defadvice! +modeline-fix-font-conflict-with-ligatures-a (&rest args)
:override #'doom-modeline-icon-material
(when doom-modeline-icon
(pcase (car args)
("save" (apply 'all-the-icons-faicon (cons "floppy-o" (plist-put (cdr args) :v-adjust -0.0575))))
(other (apply 'all-the-icons-material args))))))
(add-hook! 'magit-mode-hook
(defun +modeline-hide-in-non-status-buffer-h ()
"Show minimal modeline in magit-status buffer, no modeline elsewhere."
@ -55,32 +58,18 @@
(doom-modeline-set-project-modeline)
(hide-mode-line-mode))))
;; Remove unused segments & extra padding
(doom-modeline-def-modeline 'main
'(bar window-number matches buffer-info remote-host buffer-position selection-info)
'(objed-state misc-info persp-name irc mu4e github debug input-method buffer-encoding lsp major-mode process vcs checker))
(doom-modeline-def-modeline 'special
'(bar window-number matches buffer-info-simple buffer-position selection-info)
'(objed-state misc-info persp-name debug input-method irc buffer-encoding lsp major-mode process checker))
(doom-modeline-def-modeline 'project
'(bar window-number buffer-default-directory)
'(misc-info mu4e github debug battery " " major-mode process))
;; Some functions modify the buffer, causing the modeline to show a false
;; modified state, so force them to behave.
(defadvice! +modeline--inhibit-modification-hooks-a (orig-fn &rest args)
:around #'ws-butler-after-save
(with-silent-modifications (apply orig-fn args))))
(with-silent-modifications (apply orig-fn args)))
;;
;; Extensions
;;
;;; Extensions
(use-package! anzu
:after-call isearch-mode)
(use-package! anzu
:after-call isearch-mode)
(use-package! evil-anzu
:when (featurep! :editor evil)
:after-call evil-ex-start-search evil-ex-start-word-search evil-ex-search-activate-highlight)
(use-package! evil-anzu
:when (featurep! :editor evil)
:after-call evil-ex-start-search evil-ex-start-word-search evil-ex-search-activate-highlight))

View file

@ -1,7 +1,8 @@
;; -*- no-byte-compile: t; -*-
;;; ui/modeline/packages.el
(package! doom-modeline)
(package! anzu)
(unless (featurep! +light)
(package! doom-modeline :pin "41015d72e7"))
(package! anzu :pin "592f8ee6d0")
(when (featurep! :editor evil)
(package! evil-anzu))
(package! evil-anzu :pin "9bca6ca14d"))

View file

@ -1,4 +1,4 @@
;; -*- no-byte-compile: t; -*-
;;; ui/nav-flash/packages.el
(package! nav-flash)
(package! nav-flash :pin "dbb9121663")

View file

@ -39,10 +39,9 @@
"Collapse an expanded directory node or go to the parent node."
(interactive)
(when-let (node (neo-buffer--get-filename-current-line))
(if (file-directory-p node)
(if (neo-buffer--expanded-node-p node)
(+neotree/collapse)
(neotree-select-up-node))
(if (and (file-directory-p node)
(neo-buffer--expanded-node-p node))
(+neotree/collapse)
(neotree-select-up-node))))
;;;###autoload

View file

@ -8,14 +8,14 @@
neotree-find
neo-global--with-buffer
neo-global--window-exists-p)
:config
:init
(setq neo-create-file-auto-open nil
neo-auto-indent-point nil
neo-autorefresh nil
neo-mode-line-type 'none
neo-window-width 24
neo-window-width 30
neo-show-updir-line nil
neo-theme 'nerd ; fallback
neo-theme 'icons
neo-banner-message nil
neo-confirm-create-file #'off-p
neo-confirm-create-directory #'off-p
@ -35,6 +35,7 @@
"~$"
"^#.*#$"))
:config
(set-popup-rule! "^ ?\\*NeoTree" :ignore t)
(after! winner
@ -54,28 +55,19 @@
(skip-chars-forward " \t\r"))
(map! :map neotree-mode-map
:n "g" nil
:n "TAB" #'neotree-quick-look
:n "RET" #'neotree-enter
:n [tab] #'neotree-quick-look
:n [return] #'neotree-enter
:n [tab] (neotree-make-executor
:dir-fn #'neo-open-dir
:file-fn #'neotree-quick-look)
:n "DEL" #'evil-window-prev
:n "c" #'neotree-create-node
:n "r" #'neotree-rename-node
:n "d" #'neotree-delete-node
:n "j" #'neotree-next-line
:n "k" #'neotree-previous-line
:n "n" #'neotree-next-line
:n "p" #'neotree-previous-line
:n "h" #'+neotree/collapse-or-up
:n "l" #'+neotree/expand-or-open
:m "h" #'+neotree/collapse-or-up
:m "l" #'+neotree/expand-or-open
:n "J" #'neotree-select-next-sibling-node
:n "K" #'neotree-select-previous-sibling-node
:n "H" #'neotree-select-up-node
:n "L" #'neotree-select-down-node
:n "G" #'evil-goto-line
:n "gg" #'evil-goto-first-line
:n "v" #'neotree-enter-vertical-split
:n "s" #'neotree-enter-horizontal-split
:n "q" #'neotree-hide
:n "R" #'neotree-refresh))
:n "v" (neotree-make-executor :file-fn 'neo-open-file-vertical-split)
:n "s" (neotree-make-executor :file-fn 'neo-open-file-horizontal-split)))

View file

@ -1,4 +1,4 @@
;; -*- no-byte-compile: t; -*-
;;; ui/neotree/packages.el
(package! neotree)
(package! neotree :pin "c2420a4b34")

View file

@ -2,5 +2,5 @@
;;; ui/ophints/packages.el
(if (featurep! :editor evil)
(package! evil-goggles)
(package! volatile-highlights))
(package! evil-goggles :pin "08a22058fd")
(package! volatile-highlights :pin "9a20091f0c"))

View file

@ -9,7 +9,7 @@
;; other windows just to pop up one tiny window).
;; 2. Forcing plugins to use `display-buffer' and `pop-to-buffer' instead of
;; `switch-to-buffer' (which is unaffected by `display-buffer-alist', which
;; this module heavily relies on).
;; we must rely on, heavily).
;; 3. Closing popups (temporarily) before functions that are highly destructive
;; to the illusion of popup control get run (with the use of the
;; `save-popups!' macro).
@ -29,6 +29,18 @@
;; Don't try to resize popup windows
(advice-add #'balance-windows :around #'+popup-save-a)
(defun +popup/quit-window ()
"The regular `quit-window' sometimes kills the popup buffer and switches to a
buffer that shouldn't be in a popup. We prevent that by remapping `quit-window'
to this commmand."
(interactive)
(let ((orig-buffer (current-buffer)))
(quit-window)
(when (and (eq orig-buffer (current-buffer))
(+popup-buffer-p))
(+popup/close nil 'force))))
(global-set-key [remap quit-window] #'+popup/quit-window)
;;
;;; External functions
@ -194,17 +206,10 @@ the command buffer."
(defadvice! +popup--helm-elisp--persistent-help-a (candidate _fun &optional _name)
:before #'helm-elisp--persistent-help
(let (win)
(when (and (helm-attr 'help-running-p)
(string= candidate (helm-attr 'help-current-symbol))
(setq win (get-buffer-window (get-buffer (help-buffer)))))
(delete-window win))))
;; `helm-ag'
(defadvice! +popup--helm-pop-to-buffer-a (orig-fn &rest args)
:around #'helm-ag--edit
(pop-to-buffer
(save-window-excursion (apply orig-fn args)
(current-buffer)))))
(and (helm-attr 'help-running-p)
(string= candidate (helm-attr 'help-current-symbol))
(setq win (get-buffer-window (get-buffer (help-buffer))))
(delete-window win)))))
;;;###package Info
@ -215,16 +220,6 @@ the command buffer."
(select-window win))))
;;;###package multi-term
(setq multi-term-buffer-name "doom terminal")
;;;###package neotree
(after! neotree
(advice-add #'neo-util--set-window-width :override #'ignore)
(advice-remove #'balance-windows #'ad-Advice-balance-windows))
;;;###package org
(after! org
;; Org has a scorched-earth window management policy I'm not fond of. i.e. it
@ -239,6 +234,8 @@ the command buffer."
org-fast-todo-selection)
(if +popup-mode
(cl-letf (((symbol-function #'delete-other-windows)
(symbol-function #'ignore))
((symbol-function #'delete-window)
(symbol-function #'ignore)))
(apply orig-fn args))
(apply orig-fn args)))
@ -269,7 +266,18 @@ Ugh, such an ugly hack."
:around #'org-switch-to-buffer-other-window
(if +popup-mode
(pop-to-buffer buf nil norecord)
(funcall orig-fn buf norecord))))
(funcall orig-fn buf norecord)))
;; HACK `pop-to-buffer-same-window' consults `display-buffer-alist', which is
;; what our popup manager uses to manage popup windows. However,
;; `org-src-switch-to-buffer' already does its own window management
;; prior to calling `pop-to-buffer-same-window', so there's no need to
;; _then_ hand off the buffer to the pop up manager.
(defadvice! +popup--org-src-switch-to-buffer-a (orig-fn &rest args)
:around #'org-src-switch-to-buffer
(cl-letf (((symbol-function #'pop-to-buffer-same-window)
(symbol-function #'switch-to-buffer)))
(apply orig-fn args))))
;;;###package persp-mode
@ -315,7 +323,8 @@ Ugh, such an ugly hack."
(after! which-key
(when (eq which-key-popup-type 'side-window)
(setq which-key-popup-type 'custom
which-key-custom-popup-max-dimensions-function (lambda (_) (which-key--side-window-max-dimensions))
which-key-custom-popup-max-dimensions-function
(lambda (_) (which-key--side-window-max-dimensions))
which-key-custom-hide-popup-function #'which-key--hide-buffer-side-window
which-key-custom-show-popup-function
(lambda (act-popup-dim)
@ -323,6 +332,8 @@ Ugh, such an ugly hack."
(lambda (buffer alist)
(+popup-display-buffer-stacked-side-window-fn
buffer (append '((vslot . -9999)) alist)))))
;; HACK Fix #2219 where the which-key popup would get cut off.
(setcar act-popup-dim (1+ (car act-popup-dim)))
(which-key--show-buffer-side-window act-popup-dim))))))

View file

@ -61,24 +61,24 @@ Multiple popup rules can be defined with ~set-popup-rules!~:
(set-popup-rules!
'(("^ \\*" :slot -1) ; fallback rule for special buffers
("^\\*" :select t)
("^\\*Completions" :slot -1 :transient 0)
("^\\*\\(?:scratch\\|Messages\\)" :transient t)
("^\\*Completions" :slot -1 :ttl 0)
("^\\*\\(?:scratch\\|Messages\\)" :ttl t)
("^\\*Help" :slot -1 :size 0.2 :select t)
("^\\*doom:"
:size 0.35 :select t :modeline t :quit t :transient t)))
:size 0.35 :select t :modeline t :quit t :ttl t)))
#+END_SRC
Omitted parameters in a ~set-popup-rules!~ will use the defaults set in
~+popup-defaults~.
** Disabling hidden mode-line in popups
The mode-line is hidden in popups, by default. To disable this, you can either:
By default, the mode-line is hidden in popups. To disable this, you can either:
1. Change the default ~:modeline~ property in ~+popup-defaults~:
#+BEGIN_SRC emacs-lisp
;; put in private/$USER/config.el
(map-put +popup-defaults :modeline t)
;; add to $DOOMDIR/config.el
(plist-put +popup-defaults :modeline t)
#+END_SRC
A value of ~t~ will instruct popups to use the default mode-line. Any
@ -87,7 +87,7 @@ The mode-line is hidden in popups, by default. To disable this, you can either:
2. Completely disable management of the mode-line in popups:
#+BEGIN_SRC emacs-lisp
;; in ~/.doom.d/config.el
;; add to ~/.doom.d/config.el
(remove-hook '+popup-buffer-mode-hook #'+popup-set-modeline-on-enable-h)
#+END_SRC

View file

@ -13,26 +13,27 @@
(defun +popup--kill-buffer (buffer ttl)
"Tries to kill BUFFER, as was requested by a transient timer. If it fails, eg.
the buffer is visible, then set another timer and try again later."
(when (buffer-live-p buffer)
(let ((inhibit-quit t)
(kill-buffer-hook (remq '+popup-kill-buffer-hook-h kill-buffer-hook)))
(cond ((get-buffer-window buffer t)
(let ((inhibit-quit t))
(cond ((not (buffer-live-p buffer)))
((not (get-buffer-window buffer t))
(with-demoted-errors "Error killing transient buffer: %s"
(with-current-buffer buffer
(let ((kill-buffer-hook (remq '+popup-kill-buffer-hook-h kill-buffer-hook))
confirm-kill-processes)
(when-let (process (get-buffer-process buffer))
(kill-process process))
(let (kill-buffer-query-functions)
;; HACK The debugger backtrace buffer, when killed, called
;; `top-level'. This causes jumpiness when the popup
;; manager tries to clean it up.
(cl-letf (((symbol-function #'top-level) #'ignore))
(kill-buffer buffer)))))))
((let ((ttl (if (= ttl 0)
(or (plist-get +popup-defaults :ttl) 3)
ttl)))
(with-current-buffer buffer
(setq +popup--timer
(run-at-time ttl nil #'+popup--kill-buffer buffer ttl))))
((eq ttl 0)
(kill-buffer buffer))
((with-demoted-errors "Error killing transient buffer: %s"
(with-current-buffer buffer
(let (confirm-kill-processes)
(when-let (process (get-buffer-process buffer))
(kill-process process))
(let (kill-buffer-query-functions)
;; HACK The debugger backtrace buffer, when killed, called
;; `top-level'. This causes jumpiness when the popup
;; manager tries to clean it up.
(cl-letf (((symbol-function #'top-level) #'ignore))
(kill-buffer buffer)))))))))))
(run-at-time ttl nil #'+popup--kill-buffer buffer ttl))))))))
(defun +popup--delete-window (window)
"Do housekeeping before destroying a popup window.
@ -132,6 +133,14 @@ the buffer is visible, then set another timer and try again later."
(let ((ignore-window-parameters t))
(split-window window size side)))
(defun +popup--maybe-select-window (window origin)
"Select a window based on `+popup--inhibit-select' and this window's `select' parameter."
(unless +popup--inhibit-select
(let ((select (+popup-parameter 'select window)))
(if (functionp select)
(funcall select window origin)
(select-window (if select window origin))))))
;;;###autoload
(defun +popup--init (window &optional alist)
"Initializes a popup window. Run any time a popup is opened. It sets the
@ -172,8 +181,7 @@ and enables `+popup-buffer-mode'."
(let ((window (or window (selected-window))))
(and (windowp window)
(window-live-p window)
(or (window-parameter window 'popup)
(window-parameter window 'no-other-window))
(window-parameter window 'popup)
window))))
;;;###autoload
@ -188,18 +196,13 @@ and enables `+popup-buffer-mode'."
(alist (remove (assq 'window-height alist) alist))
(window (display-buffer-reuse-window buffer alist)))
(when window
(unless +popup--inhibit-select
(select-window window))
(+popup--maybe-select-window window origin)
window))
(when-let (popup (cl-loop for func in actions
if (funcall func buffer alist)
return it))
(+popup--init popup alist)
(unless +popup--inhibit-select
(let ((select (+popup-parameter 'select popup)))
(if (functionp select)
(funcall select popup origin)
(select-window (if select popup origin)))))
(+popup--maybe-select-window popup origin)
popup))))
;;;###autoload
@ -334,7 +337,7 @@ Any non-nil value besides the above will be used as the raw value for
'(+popup-display-buffer-stacked-side-window-fn))
(display-buffer-alist +popup--display-buffer-alist)
(buffer (current-buffer)))
(push (+popup--make "." +popup-defaults) display-buffer-alist)
(push (+popup-make-rule "." +popup-defaults) display-buffer-alist)
(bury-buffer)
(pop-to-buffer buffer)))
@ -390,8 +393,8 @@ This window parameter is ignored if FORCE-P is non-nil."
;;;###autoload
(defun +popup/toggle ()
"If popups are open, close them. If they aren't, restore the last one or open
the message buffer in a popup window."
"Toggle any visible popups.
If no popups are available, display the *Messages* buffer in a popup window."
(interactive)
(let ((+popup--inhibit-transient t))
(cond ((+popup-windows) (+popup/close-all t))
@ -412,8 +415,9 @@ the message buffer in a popup window."
;;;###autoload
(defun +popup/raise (window &optional arg)
"Raise the current popup window into a regular window.
If prefix ARG, raise the current popup into a new window."
"Raise the current popup window into a regular window and
return it. If prefix ARG, raise the current popup into a new
window and return that window."
(interactive
(list (selected-window) current-prefix-arg))
(cl-check-type window window)
@ -425,7 +429,8 @@ If prefix ARG, raise the current popup into a new window."
(+popup/close window 'force)
(if arg
(pop-to-buffer buffer)
(switch-to-buffer buffer))))
(switch-to-buffer buffer))
(selected-window)))
;;;###autoload
(defun +popup/diagnose ()

View file

@ -14,7 +14,7 @@
"Default properties for popup rules defined with `set-popup-rule!'.")
;;;###autoload
(defun +popup--make (predicate plist)
(defun +popup-make-rule (predicate plist)
(if (plist-get plist :ignore)
(list predicate nil)
(let* ((plist (append plist +popup-defaults))
@ -160,7 +160,7 @@ used.
\(fn PREDICATE &key IGNORE ACTIONS SIDE SIZE WIDTH HEIGHT SLOT VSLOT TTL QUIT SELECT MODELINE AUTOSAVE PARAMETERS)"
(declare (indent defun))
(push (+popup--make predicate plist) +popup--display-buffer-alist)
(push (+popup-make-rule predicate plist) +popup--display-buffer-alist)
(when (bound-and-true-p +popup-mode)
(setq display-buffer-alist +popup--display-buffer-alist))
+popup--display-buffer-alist)
@ -183,7 +183,7 @@ Example:
(declare (indent 0))
(dolist (rules rulesets)
(dolist (rule rules)
(push (+popup--make (car rule) (cdr rule))
(push (+popup-make-rule (car rule) (cdr rule))
+popup--display-buffer-alist)))
(when (bound-and-true-p +popup-mode)
(setq display-buffer-alist +popup--display-buffer-alist))

View file

@ -131,14 +131,16 @@ prevent the popup(s) from messing up the UI (or vice versa)."
("^ \\*" :slot 1 :vslot -1 :size +popup-shrink-to-fit)))
(when (featurep! +defaults)
'(("^\\*Completions" :ignore t)
("^\\*\\(?:Compil\\(?:ation\\|e-Log\\)\\|Messages\\)"
("^\\*Local variables\\*$"
:vslot -1 :slot 1 :size +popup-shrink-to-fit)
("^\\*\\(?:[Cc]ompil\\(?:ation\\|e-Log\\)\\|Messages\\)"
:vslot -2 :size 0.3 :autosave t :quit t :ttl nil)
("^\\*\\(?:doom \\|Pp E\\)" ; transient buffers (no interaction required)
:vslot -3 :size +popup-shrink-to-fit :autosave t :select ignore :quit t :ttl 0)
("^\\*doom:" ; editing buffers (interaction required)
:vslot -4 :size 0.35 :autosave t :select t :modeline t :quit nil :ttl t)
("^\\*doom:\\(?:v?term\\|eshell\\)-popup" ; editing buffers (interaction required)
:vslot -5 :size 0.35 :select t :modeline t :quit nil :ttl nil)
("^\\*doom:\\(?:v?term\\|e?shell\\)-popup" ; editing buffers (interaction required)
:vslot -5 :size 0.35 :select t :modeline nil :quit nil :ttl nil)
("^\\*\\(?:Wo\\)?Man "
:vslot -6 :size 0.45 :select t :quit t :ttl 0)
("^\\*Calc"
@ -158,7 +160,7 @@ prevent the popup(s) from messing up the UI (or vice versa)."
("^\\*Backtrace" :vslot 99 :size 0.4 :quit nil)
("^\\*CPU-Profiler-Report " :side bottom :vslot 100 :slot 1 :height 0.4 :width 0.5 :quit nil)
("^\\*Memory-Profiler-Report " :side bottom :vslot 100 :slot 2 :height 0.4 :width 0.5 :quit nil)
("^\\*unsent mail*" :ignore t)))
("^\\*\\(?:Proced\\|timer-list\\|Process List\\|Abbrevs\\|Output\\|Occur\\|unsent mail\\)\\*" :ignore t)))
(add-hook 'doom-init-ui-hook #'+popup-mode 'append)

View file

@ -110,7 +110,12 @@
("~>" . #Xe167)
("~~" . #Xe168)
("~~>" . #Xe169)
("%%" . #Xe16a)))
("%%" . #Xe16a)
("x" . #Xe16b)
(":" . #Xe16c)
("+" . #Xe16d)
("+" . #Xe16e)
("*" . #Xe16f)))
(defun +pretty-code-setup-fira-ligatures-h ()
(set-fontset-font t '(#Xe100 . #Xe16f) +pretty-code-fira-code-font-name)

View file

@ -15,14 +15,11 @@ and whose values are strings representing the text to be replaced with that
symbol. If the car of PLIST is nil, then unset any pretty symbols previously
defined for MODES.
The following properties are special:
This function accepts one special property:
:alist ALIST
Appends ALIST to `prettify-symbols-alist' literally, without mapping text to
`+pretty-code-symbols'.
:merge BOOL
If non-nil, merge with previously defined `prettify-symbols-alist',
otherwise overwrite it.
For example, the rule for emacs-lisp-mode is very simple:
@ -38,18 +35,17 @@ Pretty symbols can be unset for emacs-lisp-mode with:
(declare (indent defun))
(if (null (car-safe plist))
(dolist (mode (doom-enlist modes))
(delq (assq mode +pretty-code-symbols-alist)
+pretty-code-symbols-alist))
(let (results merge key)
(assq-delete-all mode +pretty-code-symbols-alist))
(let (results)
(while plist
(pcase (setq key (pop plist))
(:merge (setq merge (pop plist)))
(:alist (setq results (append (pop plist) results)))
(_
(when-let (char (plist-get +pretty-code-symbols key))
(push (cons (pop plist) char) results)))))
(let ((key (pop plist)))
(if (eq key :alist)
(prependq! results (pop plist))
(when-let (char (plist-get +pretty-code-symbols key))
(push (cons (pop plist) char) results)))))
(dolist (mode (doom-enlist modes))
(unless merge
(delq (assq mode +pretty-code-symbols-alist)
+pretty-code-symbols-alist))
(push (cons mode results) +pretty-code-symbols-alist)))))
(setf (alist-get mode +pretty-code-symbols-alist)
(if-let (old-results (alist-get mode +pretty-code-symbols-alist))
(dolist (cell results old-results)
(setf (alist-get (car cell) old-results) (cdr cell)))
results))))))

View file

@ -82,8 +82,12 @@ Otherwise it builds `prettify-code-symbols-alist' according to
(add-hook 'after-change-major-mode-hook #'+pretty-code-init-pretty-symbols-h)
;; Font-specific ligature support
(cond ((featurep! +fira)
;; The emacs-mac build of Emacs appear to have built-in support for ligatures,
;; so use that instead if this module is enabled.
(cond ((and IS-MAC (fboundp 'mac-auto-operator-composition-mode))
(mac-auto-operator-composition-mode))
;; Font-specific ligature support
((featurep! +fira)
(load! "+fira"))
((featurep! +iosevka)
(load! "+iosevka"))

View file

@ -1,77 +0,0 @@
;;; ui/tabs/autoload.el -*- lexical-binding: t; -*-
;;;###autoload
(defun +tabs-buffer-predicate (buffer)
"TODO"
(or (memq buffer (window-parameter nil 'tab-buffers))
(eq buffer (doom-fallback-buffer))))
;;
;;; Commands
;;;###autoload
(defun +tabs/close-tab-or-window ()
"TODO"
(interactive)
(call-interactively
(cond ((cdr (window-parameter nil 'tab-buffers))
#'kill-current-buffer)
((fboundp '+workspace/close-window-or-workspace)
#'+workspace/close-window-or-workspace)
(#'delete-window))))
;;
;;; Advice
;;;###autoload
(defun +tabs-kill-current-buffer-a (&rest _)
(+tabs-remove-buffer-h))
;;;###autoload
(defun +tabs-bury-buffer-a (orig-fn &rest args)
(if centaur-tabs-mode
(let ((b (current-buffer)))
(apply orig-fn args)
(unless (eq b (current-buffer))
(with-current-buffer b
(+tabs-remove-buffer-h))))
(apply orig-fn args)))
;;;###autoload
(defun +tabs-kill-tab-maybe-a (tab)
(let ((buffer (centaur-tabs-tab-value tab)))
(with-current-buffer buffer
;; `kill-current-buffer' is advised not to kill buffers visible in another
;; window, so it behaves better than `kill-buffer'.
(kill-current-buffer))
(centaur-tabs-display-update)))
;;
;;; Hooks
;;;###autoload
(defun +tabs-add-buffer-h ()
(when (and centaur-tabs-mode
(doom-real-buffer-p (current-buffer)))
(let* ((this-buf (current-buffer))
(buffers (window-parameter nil 'tab-buffers)))
(cl-pushnew this-buf buffers)
(add-hook 'kill-buffer-hook #'+tabs-remove-buffer-h nil t)
(set-window-parameter nil 'tab-buffers buffers))))
;;;###autoload
(defun +tabs-remove-buffer-h ()
(when centaur-tabs-mode
(set-window-parameter
nil
'tab-buffers (delete (current-buffer)
(window-parameter nil 'tab-buffers)))))
;;;###autoload
(defun +tabs-new-window-h ()
(when centaur-tabs-mode
(unless (window-parameter nil 'tab-buffers)
(+tabs-add-buffer-h))))

View file

@ -3,69 +3,18 @@
(use-package! centaur-tabs
:after-call after-find-file dired-initial-position-hook
:init
(setq centaur-tabs-height 28
(setq centaur-tabs-set-icons t
centaur-tabs-gray-out-icons 'buffer
centaur-tabs-set-bar 'left
centaur-tabs-set-modified-marker t)
centaur-tabs-set-modified-marker t
centaur-tabs-close-button ""
centaur-tabs-modified-marker "")
:config
(add-hook! 'centaur-tabs-mode-hook
(defun +tabs-init-frames-h ()
(dolist (frame (frame-list))
(if (not centaur-tabs-mode)
(set-frame-parameter frame 'buffer-predicate (frame-parameter frame 'old-buffer-predicate))
(set-frame-parameter frame 'old-buffer-predicate (frame-parameter frame 'buffer-predicate))
(set-frame-parameter frame 'buffer-predicate #'+tabs-buffer-predicate)))))
(add-to-list 'window-persistent-parameters '(tab-buffers . t))
(defun +tabs-window-buffer-list-fn ()
(centaur-tabs-filter-out
'centaur-tabs-hide-tab-cached
(delq nil
(cl-mapcar #'(lambda (b)
(cond
;; Always include the current buffer.
((eq (current-buffer) b) b)
((buffer-file-name b) b)
((char-equal ?\ (aref (buffer-name b) 0)) nil)
((buffer-live-p b) b)))
(window-parameter nil 'tab-buffers)))))
(defun +tabs-buffer-groups-fn ()
(list
(cond ((or (string-equal "*" (substring (buffer-name) 0 1))
(memq major-mode '(magit-process-mode
magit-status-mode
magit-diff-mode
magit-log-mode
magit-file-mode
magit-blob-mode
magit-blame-mode
)))
"Emacs")
((derived-mode-p 'eshell-mode)
"EShell")
((derived-mode-p 'dired-mode)
"Dired")
((centaur-tabs-get-group-name (current-buffer))))))
(setq centaur-tabs-buffer-list-function #'+tabs-window-buffer-list-fn
centaur-tabs-buffer-groups-function #'+tabs-buffer-groups-fn)
(advice-add #'centaur-tabs-buffer-close-tab :override #'+tabs-kill-tab-maybe-a)
(advice-add #'bury-buffer :around #'+tabs-bury-buffer-a)
(advice-add #'kill-current-buffer :before #'+tabs-kill-current-buffer-a)
(add-hook 'doom-switch-buffer-hook #'+tabs-add-buffer-h)
(add-hook 'doom-switch-window-hook #'+tabs-new-window-h)
(add-hook '+doom-dashboard-mode-hook #'centaur-tabs-local-mode)
(map! (:map centaur-tabs-mode-map
[remap delete-window] #'+tabs/close-tab-or-window
[remap +workspace/close-window-or-workspace] #'+tabs/close-tab-or-window)
(:after persp-mode
:map persp-mode-map
[remap delete-window] #'+tabs/close-tab-or-window
[remap +workspace/close-window-or-workspace] #'+tabs/close-tab-or-window))
(centaur-tabs-mode +1))
;; TODO tab-bar-mode (emacs 27)
;; TODO tab-line-mode (emacs 27)

View file

@ -1,4 +1,4 @@
;; -*- no-byte-compile: t; -*-
;;; ui/tabs/packages.el
(package! centaur-tabs)
(package! centaur-tabs :pin "96b7c90bdc")

View file

@ -2,18 +2,12 @@
(setq treemacs-follow-after-init t
treemacs-is-never-other-window t
treemacs-sorting 'alphabetic-case-insensitive-desc
treemacs-sorting 'alphabetic-case-insensitive-asc
treemacs-persist-file (concat doom-cache-dir "treemacs-persist")
treemacs-last-error-persist-file (concat doom-cache-dir "treemacs-last-error-persist"))
(after! treemacs
(set-popup-rule! "^ \\*Treemacs"
:side treemacs-position
:size treemacs-width
:quit nil
:ttl 0)
;; Don't follow the cursor
(treemacs-follow-mode -1)
@ -43,3 +37,8 @@
(use-package! treemacs-magit
:when (featurep! :tools magit)
:after treemacs magit)
(use-package! treemacs-persp
:when (featurep! :ui workspaces)
:after treemacs)

View file

@ -1,9 +1,11 @@
;; -*- no-byte-compile: t; -*-
;;; ui/treemacs/packages.el
(package! treemacs)
(package! treemacs :pin "4eb8eb8821")
(when (featurep! :editor evil +everywhere)
(package! treemacs-evil))
(package! treemacs-projectile)
(package! treemacs-evil :pin "4eb8eb8821"))
(package! treemacs-projectile :pin "4eb8eb8821")
(when (featurep! :tools magit)
(package! treemacs-magit))
(package! treemacs-magit :pin "4eb8eb8821"))
(when (featurep! :ui workspaces)
(package! treemacs-persp :pin "4eb8eb8821"))

View file

@ -3,7 +3,7 @@
;;;###autoload
(add-hook! 'doom-init-ui-hook
(defun +unicode-init-fonts-h ()
"Set up `unicode-fonts' to eventually run; accomodating the daemon, if
"Set up `unicode-fonts' to eventually run; accommodating the daemon, if
necessary."
(setq-default bidi-display-reordering t
doom-unicode-font nil)

View file

@ -1,4 +1,4 @@
;; -*- no-byte-compile: t; -*-
;;; ui/unicode/packages.el
(package! unicode-fonts)
(package! unicode-fonts :pin "7b88ae84e5")

View file

@ -11,9 +11,9 @@
diffing, even for unsaved buffers.")
(defvar +vc-gutter-default-style t
"If non-nil, enable the default look of the vc gutter. This means subtle thin
bitmaps on the left, an arrow bitmap for flycheck, and flycheck indicators moved
to the right fringe.")
"If non-nil, enable the default look of the vc gutter.
This means subtle thin bitmaps on the left, an arrow bitmap for flycheck, and
flycheck indicators moved to the right fringe.")
;;
@ -28,27 +28,28 @@ to the right fringe.")
If the buffer doesn't represent an existing file, `git-gutter-mode's activation
is deferred until the file is saved. Respects `git-gutter:disabled-modes'."
(when (or +vc-gutter-in-remote-files
(not (file-remote-p (or buffer-file-name default-directory))))
(if (not buffer-file-name)
(add-hook 'after-save-hook #'+vc-gutter-init-maybe-h nil 'local)
(when (and (vc-backend buffer-file-name)
(progn
(require 'git-gutter)
(not (memq major-mode git-gutter:disabled-modes))))
(if (and (display-graphic-p)
(require 'git-gutter-fringe nil t))
(progn
(setq-local git-gutter:init-function #'git-gutter-fr:init)
(setq-local git-gutter:view-diff-function #'git-gutter-fr:view-diff-infos)
(setq-local git-gutter:clear-function #'git-gutter-fr:clear)
(setq-local git-gutter:window-width -1))
(setq-local git-gutter:init-function 'nil)
(setq-local git-gutter:view-diff-function #'git-gutter:view-diff-infos)
(setq-local git-gutter:clear-function #'git-gutter:clear-diff-infos)
(setq-local git-gutter:window-width 1))
(git-gutter-mode +1)
(remove-hook 'after-save-hook #'+vc-gutter-init-maybe-h 'local))))))
(let ((file-name (buffer-file-name (buffer-base-buffer))))
(when (or +vc-gutter-in-remote-files
(not (file-remote-p (or file-name default-directory))))
(if (null file-name)
(add-hook 'after-save-hook #'+vc-gutter-init-maybe-h nil 'local)
(when (and (vc-backend file-name)
(progn
(require 'git-gutter)
(not (memq major-mode git-gutter:disabled-modes))))
(if (and (display-graphic-p)
(require 'git-gutter-fringe nil t))
(progn
(setq-local git-gutter:init-function #'git-gutter-fr:init)
(setq-local git-gutter:view-diff-function #'git-gutter-fr:view-diff-infos)
(setq-local git-gutter:clear-function #'git-gutter-fr:clear)
(setq-local git-gutter:window-width -1))
(setq-local git-gutter:init-function 'nil)
(setq-local git-gutter:view-diff-function #'git-gutter:view-diff-infos)
(setq-local git-gutter:clear-function #'git-gutter:clear-diff-infos)
(setq-local git-gutter:window-width 1))
(git-gutter-mode +1)
(remove-hook 'after-save-hook #'+vc-gutter-init-maybe-h 'local)))))))
;; Disable in Org mode, as per
;; <https://github.com/syl20bnr/spacemacs/issues/10555> and
@ -58,9 +59,6 @@ is deferred until the file is saved. Respects `git-gutter:disabled-modes'."
;; assigned. I don't know why this is the case, but adding `fundamental-mode'
;; here fixes the issue.
(setq git-gutter:disabled-modes '(fundamental-mode image-mode pdf-view-mode))
;; standardize default fringe width
(if (fboundp 'fringe-mode) (fringe-mode '4))
:config
(set-popup-rule! "^\\*git-gutter" :select nil :size '+popup-shrink-to-fit)
@ -93,6 +91,9 @@ is deferred until the file is saved. Respects `git-gutter:disabled-modes'."
;; subtle diff indicators in the fringe
(when +vc-gutter-default-style
;; standardize default fringe width
(if (fboundp 'fringe-mode) (fringe-mode '4))
(after! git-gutter-fringe
;; places the git gutter outside the margins.
(setq-default fringes-outside-margins t)
@ -102,10 +103,10 @@ is deferred until the file is saved. Respects `git-gutter:disabled-modes'."
(define-fringe-bitmap 'git-gutter-fr:modified [224]
nil nil '(center repeated))
(define-fringe-bitmap 'git-gutter-fr:deleted [128 192 224 240]
nil nil 'bottom)
nil nil 'bottom))
(after! flycheck
;; let diff have left fringe, flycheck can have right fringe
(after! flycheck
(setq flycheck-indication-mode 'right-fringe)
;; A non-descript, left-pointing arrow
(define-fringe-bitmap 'flycheck-fringe-bitmap-double-arrow
[16 48 112 240 112 48 16] nil nil 'center))))
(setq flycheck-indication-mode 'right-fringe)
;; A non-descript, left-pointing arrow
(define-fringe-bitmap 'flycheck-fringe-bitmap-double-arrow
[16 48 112 240 112 48 16] nil nil 'center)))

View file

@ -1,4 +1,4 @@
;; -*- no-byte-compile: t; -*-
;;; ui/vc-gutter/packages.el
(package! git-gutter-fringe)
(package! git-gutter-fringe :pin "16226caab4")

View file

@ -1,4 +1,4 @@
;; -*- no-byte-compile: t; -*-
;;; ui/vi-tilde-fringe/packages.el
(package! vi-tilde-fringe)
(package! vi-tilde-fringe :pin "f1597a8d54")

View file

@ -15,13 +15,11 @@
* Description
This module provides several methods for selecting windows without the use of
the mouse or spatial navigation (e.g. =C-w {h,j,k,l}=). The command
~other-window~ is remapped to either ~switch-window~ or ~ace-window~, depending
on which backend you've enabled.
the mouse or spatial navigation (e.g. =C-w {h,j,k,l}=).
#+begin_quote
~other-window~ is bound to ~C-x o~ and ~SPC w o~.
#+end_quote
The command ~other-window~ is remapped to either ~switch-window~ or
~ace-window~, depending on which backend you've enabled. It is bound to ~C-x o~
(and ~C-w C-w~ for evil users).
It also provides numbered windows and selection with the ~winum~ package, if
desired. Evil users can jump to window N in =C-w <N>= (where N is a number

View file

@ -16,8 +16,9 @@
:init
(global-set-key [remap other-window] #'ace-window)
:config
(setq aw-keys '(?a ?s ?d ?f ?g ?h ?j ?k ?l)
aw-scope 'frame
(unless (featurep! +numbers)
(setq aw-keys '(?a ?s ?d ?f ?g ?h ?j ?k ?l)))
(setq aw-scope 'frame
aw-background t))

View file

@ -2,8 +2,8 @@
;;; ui/window-select/packages.el
(if (featurep! +switch-window)
(package! switch-window)
(package! ace-window))
(package! switch-window :pin "204f9fc1a3")
(package! ace-window :pin "7e0777b39a"))
(when (featurep! +numbers)
(package! winum))
(package! winum :pin "c5455e866e"))

View file

@ -68,20 +68,19 @@ error if NAME doesn't exist."
"Return a list of workspace structs (satisifes `+workspace-p')."
;; We don't use `hash-table-values' because it doesn't ensure order in older
;; versions of Emacs
(cdr (cl-loop for persp being the hash-values of *persp-hash*
collect persp)))
(cl-loop for name in persp-names-cache
if (gethash name *persp-hash*)
collect it))
;;;###autoload
(defun +workspace-list-names ()
"Return the list of names of open workspaces."
(mapcar #'safe-persp-name (+workspace-list)))
persp-names-cache)
;;;###autoload
(defun +workspace-buffer-list (&optional persp)
"Return a list of buffers in PERSP.
The buffer list is ordered by recency (same as `buffer-list').
PERSP can be a string (name of a workspace) or a workspace (satisfies
`+workspace-p'). If nil or omitted, it defaults to the current workspace."
(let ((persp (or persp (+workspace-current))))
@ -174,11 +173,12 @@ throws an error."
(+workspace-new name)
(error "%s is not an available workspace" name)))
(let ((old-name (+workspace-current-name)))
(setq +workspace--last
(or (and (not (string= old-name persp-nil-name))
old-name)
+workspaces-main))
(persp-frame-switch name)
(unless (equal old-name name)
(setq +workspace--last
(or (and (not (string= old-name persp-nil-name))
old-name)
+workspaces-main))
(persp-frame-switch name))
(equal (+workspace-current-name) name)))
@ -268,13 +268,20 @@ workspace to delete."
('error (+workspace-error ex t))))
;;;###autoload
(defun +workspace/kill-session ()
(defun +workspace/kill-session (&optional interactive)
"Delete the current session, all workspaces, windows and their buffers."
(interactive)
(unless (cl-every #'+workspace-delete (+workspace-list-names))
(+workspace-error "Could not clear session"))
(+workspace-switch +workspaces-main t)
(doom/kill-all-buffers (buffer-list)))
(interactive (list t))
(let ((windows (length (window-list)))
(persps (length (+workspace-list-names)))
(buffers 0))
(let ((persp-autokill-buffer-on-remove t))
(unless (cl-every #'+workspace-delete (+workspace-list-names))
(+workspace-error "Could not clear session")))
(+workspace-switch +workspaces-main t)
(setq buffers (doom/kill-all-buffers (buffer-list)))
(when interactive
(message "Killed %d workspace(s), %d window(s) & %d buffer(s)"
persps windows buffers))))
;;;###autoload
(defun +workspace/kill-session-and-quit ()
@ -305,7 +312,12 @@ workspace, otherwise the new workspace is blank."
end of the workspace list."
(interactive
(list (or current-prefix-arg
(completing-read "Switch to workspace: " (+workspace-list-names)))))
(if (featurep! :completion ivy)
(ivy-read "Switch to workspace: "
(+workspace-list-names)
:caller #'+workspace/switch-to
:preselect (+workspace-current-name))
(completing-read "Switch to workspace: " (+workspace-list-names))))))
(when (and (stringp index)
(string-match-p "^[0-9]+$" index))
(setq index (string-to-number index)))
@ -318,9 +330,7 @@ end of the workspace list."
(error "No workspace at #%s" (1+ index)))
(+workspace-switch dest)))
((stringp index)
(unless (member index names)
(error "No workspace named %s" index))
(+workspace-switch index))
(+workspace-switch index t))
(t
(error "Not a valid index: %s" index)))
(unless (called-interactively-p 'interactive)
@ -332,7 +342,8 @@ end of the workspace list."
;;;###autoload
(dotimes (i 9)
(defalias (intern (format "+workspace/switch-to-%d" i))
(lambda () (interactive) (+workspace/switch-to i))))
(lambda () (interactive) (+workspace/switch-to i))
(format "Switch to workspace #%d" (1+ i))))
;;;###autoload
(defun +workspace/switch-to-final ()
@ -393,6 +404,31 @@ the next."
((+workspace-error "Can't delete last workspace" t)))))))
;;;###autoload
(defun +workspace/swap-left (&optional count)
"Swap the current workspace with the COUNTth workspace on its left."
(interactive "p")
(let* ((current-name (+workspace-current-name))
(count (or count 1))
(index (- (cl-position current-name persp-names-cache :test #'equal)
count))
(names (remove current-name persp-names-cache)))
(unless names
(user-error "Only one workspace"))
(let ((index (min (max 0 index) (length names))))
(setq persp-names-cache
(append (cl-subseq names 0 index)
(list current-name)
(cl-subseq names index))))
(when (called-interactively-p 'any)
(+workspace/display))))
;;;###autoload
(defun +workspace/swap-right (&optional count)
"Swap the current workspace with the COUNTth workspace on its right."
(interactive "p")
(funcall-interactively #'+workspace/swap-left (- count)))
;;
;;; Tabs display in minibuffer
@ -490,9 +526,16 @@ This be hooked to `projectile-after-switch-project-hook'."
(when dir
(setq +workspaces--project-dir dir))
(when (and persp-mode +workspaces--project-dir)
(with-temp-buffer
;; Load the project dir-local variables into the switch buffer, so the
;; action can make use of them
(setq default-directory +workspaces--project-dir)
(hack-dir-local-variables-non-file-buffer)
(run-hooks 'projectile-before-switch-project-hook))
(unwind-protect
(if (and (not (null +workspaces-on-switch-project-behavior))
(or (eq +workspaces-on-switch-project-behavior t)
(equal (safe-persp-name (get-current-persp)) persp-nil-name)
(+workspace-buffer-list)))
(let* ((persp
(let ((project-name (doom-project-name +workspaces--project-dir)))
@ -514,6 +557,7 @@ This be hooked to `projectile-after-switch-project-hook'."
(+workspace-rename (+workspace-current-name) (doom-project-name +workspaces--project-dir)))
(unless current-prefix-arg
(funcall +workspaces-switch-project-function +workspaces--project-dir)))
(run-hooks 'projectile-after-switch-project-hook)
(setq +workspaces--project-dir nil))))

View file

@ -62,28 +62,37 @@ stored in `persp-save-dir'.")
(advice-add #'persp-asave-on-exit :around #'+workspaces-autosave-real-buffers-a)
(add-hook! '(persp-mode-hook persp-after-load-state-functions)
(defun +workspaces-ensure-main-workspace-h (&rest _)
"Ensure the main workspace exists and the nil workspace is never active."
(defun +workspaces-ensure-no-nil-workspaces-h (&rest _)
(when persp-mode
(let (persp-before-switch-functions)
;; The default perspective persp-mode creates (`persp-nil-name') is
;; special and doesn't represent a real persp object, so buffers can't
;; really be assigned to it, among other quirks. We create a *real* main
;; workspace to fill this role.
(unless (persp-get-by-name +workspaces-main)
(persp-add-new +workspaces-main))
;; Switch to it if we're in the nil perspective
(dolist (frame (frame-list))
(when (string= (safe-persp-name (get-current-persp frame)) persp-nil-name)
(persp-frame-switch +workspaces-main frame)
;; Fix #319: the warnings buffer gets swallowed by creating
;; `+workspaces-main', so we display it manually, if it exists.
(when-let (warnings (get-buffer "*Warnings*"))
(save-excursion
(display-buffer-in-side-window
warnings '((window-height . shrink-window-if-larger-than-buffer)))))))))))
(dolist (frame (frame-list))
(when (string= (safe-persp-name (get-current-persp frame)) persp-nil-name)
;; Take extra steps to ensure no frame ends up in the nil perspective
(persp-frame-switch (or (cadr (hash-table-keys *persp-hash*))
+workspaces-main)
frame))))))
(add-hook! 'persp-mode-hook
(defun +workspaces-init-first-workspace-h (&rest _)
"Ensure a main workspace exists."
(when persp-mode
(let (persp-before-switch-functions)
;; The default perspective persp-mode creates is special and doesn't
;; represent a real persp object, so buffers can't really be assigned
;; to it, among other quirks. We hide the nil persp...
(when (equal (car persp-names-cache) persp-nil-name)
(pop persp-names-cache))
;; ...and create a *real* main workspace to fill this role, and hide
;; the nil perspective.
(unless (or (persp-get-by-name +workspaces-main)
;; Start from 2 b/c persp-mode counts the nil workspace
(> (hash-table-count *persp-hash*) 2))
(persp-add-new +workspaces-main))
;; HACK Fix #319: the warnings buffer gets swallowed when creating
;; `+workspaces-main', so display it ourselves, if it exists.
(when-let (warnings (get-buffer "*Warnings*"))
(save-excursion
(display-buffer-in-side-window
warnings '((window-height . shrink-window-if-larger-than-buffer))))))))
(defun +workspaces-init-persp-mode-h ()
(cond (persp-mode
;; `uniquify' breaks persp-mode. It renames old buffers, which causes
@ -108,15 +117,15 @@ stored in `persp-save-dir'.")
;; add buffers when they are switched to.
(setq persp-add-buffer-on-find-file nil
persp-add-buffer-on-after-change-major-mode nil)
(add-hook! '(doom-switch-buffer-hook server-visit-hook)
(defun +workspaces-add-current-buffer-h ()
"Add current buffer to focused perspective."
(and persp-mode
(not (persp-buffer-filtered-out-p
(current-buffer)
persp-add-buffer-on-after-change-major-mode-filter-functions))
(persp-add-buffer (current-buffer) (get-current-persp) nil nil))))
(or (not persp-mode)
(persp-buffer-filtered-out-p
(or (buffer-base-buffer (current-buffer))
(current-buffer))
persp-add-buffer-on-after-change-major-mode-filter-functions)
(persp-add-buffer (current-buffer) (get-current-persp) nil nil))))
(add-hook 'persp-add-buffer-on-after-change-major-mode-filter-functions
#'doom-unreal-buffer-p)
@ -162,15 +171,15 @@ stored in `persp-save-dir'.")
("C" counsel-projectile-switch-project-action-configure "run project configure command")
("e" counsel-projectile-switch-project-action-edit-dir-locals "edit project dir-locals")
("v" counsel-projectile-switch-project-action-vc "open project in vc-dir / magit / monky")
("s" (lambda (project) (let ((projectile-switch-project-action (lambda () (call-interactively #'+ivy/project-search))))
(counsel-projectile-switch-project-by-name project))) "search project")
("s" (lambda (project)
(let ((projectile-switch-project-action
(lambda () (call-interactively #'+ivy/project-search))))
(counsel-projectile-switch-project-by-name project))) "search project")
("xs" counsel-projectile-switch-project-action-run-shell "invoke shell from project root")
("xe" counsel-projectile-switch-project-action-run-eshell "invoke eshell from project root")
("xt" counsel-projectile-switch-project-action-run-term "invoke term from project root")
("X" counsel-projectile-switch-project-action-org-capture "org-capture into project")))
(add-hook 'projectile-after-switch-project-hook #'+workspaces-switch-to-project-h)
;; Fix #1973: visual selection surviving workspace changes
(add-hook 'persp-before-deactivate-functions #'deactivate-mark)

View file

@ -1,5 +1,4 @@
;; -*- no-byte-compile: t; -*-
;;; ui/workspaces/packages.el
(package! persp-mode)
(package! persp-mode :pin "e330e6240b")

51
modules/ui/zen/README.org Normal file
View file

@ -0,0 +1,51 @@
#+TITLE: ui/zen
#+DATE: December 20, 2019
#+SINCE: v3.0.0
#+STARTUP: inlineimages
* Table of Contents :TOC_3:noexport:
- [[#description][Description]]
- [[#module-flags][Module Flags]]
- [[#plugins][Plugins]]
- [[#hacks][Hacks]]
- [[#prerequisites][Prerequisites]]
- [[#features][Features]]
- [[#distractions-free-mode][Distractions-free mode]]
- [[#configuration][Configuration]]
- [[#enable-fullscreen-on-activation][Enable fullscreen on activation]]
* Description
This module provides ~writeroom-mode~, which transforms Emacs into a
comfortable writing or coding space by centering the buffer, removing
superfluous UI elements, and turning on variable-pitch fonts (but keeps certain
elements fixed-pitch, where it makes sense to).
If you've used olivetti, sublimity, or tabula-rasa, you will feel right at home.
** Module Flags
This module provides no flags.
** Plugins
+ [[https://github.com/joostkremers/writeroom-mode][writeroom-mode]]
+ [[https://gitlab.com/jabranham/mixed-pitch][mixed-pitch]]
** Hacks
+ =mixed-pitch= has been modified not to override ~:height~ properties on the
faces it remaps. This means text-scale can affect the ~fixed-pitch~ faces as
well; See https://gitlab.com/jabranham/mixed-pitch/issues/6#note_79691741.
* Prerequisites
This module has no prereqisites.
* Features
** Distractions-free mode
This can be activated with =SPC t z= for evil users. There is no keybinding for
non-evil users yet, so use 'M-x writeroom-mode'.
* Configuration
** Enable fullscreen on activation
#+BEGIN_SRC elisp
(setq writeroom-fullscreen-effect t)
#+END_SRC
Or fullscreen manually with =SPC t F= (or =F11= for non-evil users).

64
modules/ui/zen/config.el Normal file
View file

@ -0,0 +1,64 @@
;;; ui/zen/config.el -*- lexical-binding: t; -*-
(defvar +zen-mixed-pitch-modes '(markdown-mode org-mode)
"What major-modes to enable `mixed-pitch-mode' in with `writeroom-mode'.")
(defvar +zen-text-scale 2
"The text-scaling level for `writeroom-mode'.")
;;
;;; Packages
(after! writeroom-mode
;; Users should be able to activate writeroom-mode in one buffer (e.g. an org
;; buffer) and code in another. Fullscreening/maximizing will be opt-in.
(setq writeroom-maximize-window nil)
(remove-hook 'writeroom-global-effects 'writeroom-set-fullscreen)
(add-hook! 'writeroom-mode-hook
(defun +zen-enable-text-scaling-mode-h ()
"Enable `mixed-pitch-mode' when in `+zen-mixed-pitch-modes'."
(when (/= +zen-text-scale 0)
(text-scale-set (if writeroom-mode +zen-text-scale 0))
(visual-fill-column-adjust))))
;; Adjust margins when text size is changed
(advice-add #'text-scale-adjust :after #'visual-fill-column-adjust))
(use-package! mixed-pitch
:hook (writeroom-mode . +zen-enable-mixed-pitch-mode-h)
:config
(defun +zen-enable-mixed-pitch-mode-h ()
"Enable `mixed-pitch-mode' when in `+zen-mixed-pitch-modes'."
(when (apply #'derived-mode-p +zen-mixed-pitch-modes)
(mixed-pitch-mode (if writeroom-mode +1 -1))))
(pushnew! mixed-pitch-fixed-pitch-faces
'org-date
'org-special-keyword
'org-property-value
'org-ref-cite-face
'org-tag
'org-todo-keyword-todo
'org-todo-keyword-habt
'org-todo-keyword-done
'org-todo-keyword-wait
'org-todo-keyword-kill
'org-todo-keyword-outd
'org-todo
'org-indent
'font-lock-comment-face
'line-number
'line-number-current-line)
;; See https://gitlab.com/jabranham/mixed-pitch/issues/6#note_79691741
(defadvice! +zen--fix-scaled-fixed-pitch-faces-a (orig-fn &rest args)
:around #'mixed-pitch-mode
(cl-letf* ((old-face-remap-add-relative (symbol-function #'face-remap-add-relative))
((symbol-function #'face-remap-add-relative)
(lambda (face &rest specs)
(funcall old-face-remap-add-relative
face (doom-plist-delete specs :height)))))
(apply orig-fn args))))

View file

@ -0,0 +1,5 @@
;; -*- no-byte-compile: t; -*-
;;; ui/zen/packages.el
(package! writeroom-mode :pin "fa17eb6511")
(package! mixed-pitch :pin "fbc566ace3")