mirror of
https://gitlab.com/dwt1/dotfiles.git
synced 2026-04-23 19:40:24 +10:00
Updating Doom Emacs.
This commit is contained in:
@@ -3,21 +3,35 @@
|
||||
(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
|
||||
;; disable auto-save
|
||||
deft-auto-save-interval -1.0
|
||||
;; 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
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; ui/deft/packages.el
|
||||
|
||||
(package! deft)
|
||||
(package! deft :pin "fca9ea05ef4fdac825e2ad3921baa7042f6b82c8")
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,45 @@ 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 +237,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 +280,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 +383,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 +428,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 +453,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 +469,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 +481,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")
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#+TITLE: ui/doom
|
||||
#+DATE: October 9, 2019
|
||||
#+SINCE: v1.3
|
||||
#+STARTUP: inlineimages
|
||||
#+STARTUP: inlineimages nofold
|
||||
|
||||
* Table of Contents :TOC_3:noexport:
|
||||
- [[#description][Description]]
|
||||
|
||||
@@ -1,36 +1,15 @@
|
||||
;;; ui/doom/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
(defvar +doom-solaire-themes
|
||||
'((doom-challenger-deep . t)
|
||||
(doom-city-lights . t)
|
||||
(doom-dracula . t)
|
||||
(doom-molokai)
|
||||
(doom-nord . t)
|
||||
(doom-nord-light . t)
|
||||
(doom-nova)
|
||||
(doom-one . t)
|
||||
(doom-one-light . t)
|
||||
(doom-opera . t)
|
||||
(doom-snazzy . t)
|
||||
(doom-solarized-dark . t)
|
||||
(doom-solarized-light)
|
||||
(doom-spacegrey . t)
|
||||
(doom-tomorrow-day . t)
|
||||
(doom-tomorrow-night . t)
|
||||
(doom-vibrant))
|
||||
"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.")
|
||||
;;;###package pos-tip
|
||||
(setq pos-tip-internal-border-width 6
|
||||
pos-tip-border-width 1)
|
||||
|
||||
|
||||
;;
|
||||
;;; Packages
|
||||
|
||||
(use-package! doom-themes
|
||||
:defer t
|
||||
:init
|
||||
(unless doom-theme
|
||||
(setq doom-theme 'doom-one))
|
||||
:config
|
||||
;; improve integration w/ org-mode
|
||||
(add-hook 'doom-load-theme-hook #'doom-themes-org-config)
|
||||
;; more Atom-esque file icons for neotree/treemacs
|
||||
@@ -45,52 +24,64 @@
|
||||
|
||||
(use-package! solaire-mode
|
||||
:when (or (daemonp) (display-graphic-p))
|
||||
:defer t
|
||||
:init
|
||||
(add-hook! 'doom-load-theme-hook :append
|
||||
(defun +doom-solaire-mode-swap-bg-maybe-h ()
|
||||
(pcase-let ((`(,_theme . ,swap) (assq doom-theme +doom-solaire-themes)))
|
||||
(require 'solaire-mode)
|
||||
(if swap (solaire-mode-swap-bg)))))
|
||||
:hook (doom-load-theme . solaire-global-mode)
|
||||
:config
|
||||
;; fringe can become unstyled when deleting or focusing frames
|
||||
(add-hook 'focus-in-hook #'solaire-mode-reset)
|
||||
;; Prevent color glitches when reloading either DOOM or loading a new theme
|
||||
(add-hook! '(doom-load-theme-hook doom-reload-hook) :append
|
||||
#'solaire-mode-reset)
|
||||
;; org-capture takes an org buffer and narrows it. The result is erroneously
|
||||
;; considered an unreal buffer, so solaire-mode must be restored.
|
||||
(add-hook 'org-capture-mode-hook #'turn-on-solaire-mode)
|
||||
(when (daemonp)
|
||||
(add-hook! '(doom-switch-frame-hook after-make-frame-functions)
|
||||
(defun +doom-disable-solaire-mode-maybe-h (&optional frame)
|
||||
(if (display-graphic-p frame)
|
||||
(unless solaire-global-mode
|
||||
(solaire-global-mode +1))
|
||||
(when solaire-global-mode
|
||||
(solaire-global-mode -1))))))
|
||||
|
||||
;; On Emacs 26+, when point is on the last line and solaire-mode is remapping
|
||||
;; the hl-line face, hl-line's highlight bleeds into the rest of the window
|
||||
;; after eob. On Emacs 27 this no longer happens.
|
||||
(add-hook! 'solaire-global-mode-hook
|
||||
(defun +doom-solaire-swap-bg-faces-maybe-h ()
|
||||
(and solaire-global-mode
|
||||
(string-prefix-p "doom-" (symbol-name doom-theme))
|
||||
(solaire-mode-swap-bg))))
|
||||
|
||||
;; DEPRECATED No longer needed in Emacs 27+
|
||||
(unless EMACS27+
|
||||
;; HACK On Emacs <=26, when point is on the last (or second to last) line
|
||||
;; and solaire-mode is remapping the hl-line face, hl-line's highlight
|
||||
;; bleeds into the rest of the window after eob. On Emacs 27 this no
|
||||
;; longer happens. This tries to fix it for 26 users, but it imposes
|
||||
;; another problem: the 2nd-to-last line will only be highlighted up to
|
||||
;; the (n-1)th character, but I think that is the lesser evil.
|
||||
(defun +doom--line-range-fn ()
|
||||
(cons (line-beginning-position)
|
||||
(cond ((let ((eol (line-end-position)))
|
||||
(and (= eol (point-max))
|
||||
(/= eol (line-beginning-position))))
|
||||
(1- (line-end-position)))
|
||||
((or (eobp)
|
||||
(= (line-end-position 2) (point-max)))
|
||||
(line-end-position))
|
||||
((line-beginning-position 2)))))
|
||||
(setq hl-line-range-function #'+doom--line-range-fn))
|
||||
(if solaire-mode
|
||||
(let ((bol (line-beginning-position))
|
||||
(eol (line-end-position))
|
||||
(eob (point-max)))
|
||||
(cond ((= bol eob)
|
||||
nil)
|
||||
((= (1+ eol) eob)
|
||||
(cons bol (1- eob)))
|
||||
((or (= eol eob) (eobp))
|
||||
(cons bol eol))
|
||||
((cons bol (line-beginning-position 2)))))
|
||||
(cons (line-beginning-position)
|
||||
(line-beginning-position 2))))
|
||||
(setq hl-line-range-function #'+doom--line-range-fn)
|
||||
|
||||
;; Because fringes can't be given a buffer-local face, they can look odd, so
|
||||
;; we remove them in the minibuffer and which-key popups (they serve no
|
||||
;; purpose there anyway).
|
||||
(add-hook! 'solaire-mode-hook
|
||||
(defun +doom-disable-fringes-in-minibuffer-h (&rest _)
|
||||
(set-window-fringes (minibuffer-window) 0 0 nil)))
|
||||
;; HACK The fringe cannot have a buffer-local remapping on Emacs <= 26, so
|
||||
;; we jump through hoops to reset it (globally) whenever it is likely
|
||||
;; that the fringe will have lost its background color.
|
||||
(add-hook! '(doom-load-theme-hook doom-reload-hook) :append
|
||||
#'solaire-mode-reset)
|
||||
|
||||
(defadvice! +doom--no-fringes-in-which-key-buffer-a (&rest _)
|
||||
:after 'which-key--show-buffer-side-window
|
||||
(+doom-disable-fringes-in-minibuffer-h)
|
||||
(set-window-fringes (get-buffer-window which-key--buffer) 0 0 nil))
|
||||
;; fringe can become unstyled when deleting or focusing frames
|
||||
(add-hook 'focus-in-hook #'solaire-mode-reset)
|
||||
|
||||
(add-hook! '(minibuffer-setup-hook window-configuration-change-hook)
|
||||
#'+doom-disable-fringes-in-minibuffer-h)
|
||||
|
||||
(solaire-global-mode +1))
|
||||
;; A global fringe color means the minibuffer (with its fringes) will always
|
||||
;; stand out, so we remove them (in which-key popups too).
|
||||
(add-hook! 'solaire-mode-hook
|
||||
(defun +doom-disable-fringes-in-minibuffer-h (&rest _)
|
||||
(set-window-fringes (minibuffer-window) 0 0 nil)))
|
||||
(defadvice! +doom--no-fringes-in-which-key-buffer-a (&rest _)
|
||||
:after 'which-key--show-buffer-side-window
|
||||
(+doom-disable-fringes-in-minibuffer-h)
|
||||
(set-window-fringes (get-buffer-window which-key--buffer) 0 0 nil))
|
||||
(add-hook! '(minibuffer-setup-hook window-configuration-change-hook)
|
||||
#'+doom-disable-fringes-in-minibuffer-h)))
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; ui/doom/packages.el
|
||||
|
||||
(package! doom-themes)
|
||||
(package! solaire-mode)
|
||||
|
||||
(package! doom-themes :pin "b1c43a324d3000bd9972030aecf98c9cc8376337")
|
||||
(package! solaire-mode :pin "25d1aafc03e3c7f9487532464dbffacce10d0c5d")
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
;;; ui/fill-column/autoload.el -*- lexical-binding: t; -*-
|
||||
|
||||
;; DEPRECATED Replaced by `display-fill-column-indicator-mode' in Emacs 27+
|
||||
|
||||
;;;###autoload (autoload 'hl-fill-column-mode "hl-fill-column" nil t)
|
||||
|
||||
;;;###autoload
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; ui/fill-column/packages.el
|
||||
|
||||
(package! hl-fill-column)
|
||||
(package! hl-fill-column :pin "43cb3c35a92c912b7205b8a36f1ad0ec0a5b4a22")
|
||||
|
||||
@@ -5,13 +5,30 @@
|
||||
:config
|
||||
(setq hl-todo-highlight-punctuation ":"
|
||||
hl-todo-keyword-faces
|
||||
`(("TODO" warning bold)
|
||||
("FIXME" error bold)
|
||||
("HACK" font-lock-constant-face bold)
|
||||
("REVIEW" font-lock-keyword-face bold)
|
||||
("NOTE" success bold)
|
||||
`(;; For things that need to be done, just not today.
|
||||
("TODO" warning bold)
|
||||
;; For problems that will become bigger problems later if not
|
||||
;; fixed ASAP.
|
||||
("FIXME" error bold)
|
||||
;; For tidbits that are unconventional and not intended uses of the
|
||||
;; constituent parts, and may break in a future update.
|
||||
("HACK" font-lock-constant-face bold)
|
||||
;; For things that were done hastily and/or hasn't been thoroughly
|
||||
;; tested. It may not even be necessary!
|
||||
("REVIEW" font-lock-keyword-face bold)
|
||||
;; For especially important gotchas with a given implementation,
|
||||
;; directed at another user other than the author.
|
||||
("NOTE" success bold)
|
||||
;; For things that just gotta go and will soon be gone.
|
||||
("DEPRECATED" font-lock-doc-face bold)))
|
||||
|
||||
(defadvice! +hl-todo-clamp-font-lock-fontify-region-a (orig-fn &rest args)
|
||||
"Fix an `args-out-of-range' error in some modes."
|
||||
:around #'hl-todo-mode
|
||||
(letf! (defun font-lock-fontify-region (beg end &optional loudly)
|
||||
(funcall font-lock-fontify-region (max beg 1) end loudly))
|
||||
(apply orig-fn args)))
|
||||
|
||||
;; Use a more primitive todo-keyword detection method in major modes that
|
||||
;; don't use/have a valid syntax table entry for comments.
|
||||
(add-hook! '(pug-mode-hook haml-mode-hook)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; ui/hl-todo/packages.el
|
||||
|
||||
(package! hl-todo)
|
||||
(package! hl-todo :pin "3bba4591c54951d2abab113ec5e58a6319808ca9")
|
||||
|
||||
@@ -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
|
||||
"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; ui/hydra/packages.el
|
||||
|
||||
(package! hydra)
|
||||
(package! hydra :pin "87873d788891029d9e44fa5458321d6a05849b94")
|
||||
|
||||
@@ -5,9 +5,21 @@
|
||||
:init
|
||||
(setq highlight-indent-guides-method 'character)
|
||||
: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)
|
||||
(defun +indent-guides-init-faces-h ()
|
||||
(when (display-graphic-p)
|
||||
(highlight-indent-guides-auto-set-faces)))
|
||||
|
||||
;; HACK `highlight-indent-guides' calculates its faces from the current theme,
|
||||
;; but is unable to do so properly in terminal Emacs, where it only has
|
||||
;; access to 256 colors. So if the user uses a daemon we must wait for
|
||||
;; the first graphical frame to be available to do.
|
||||
(add-hook (if (daemonp)
|
||||
'server-after-make-frame-hook
|
||||
'doom-load-theme-hook)
|
||||
#'+indent-guides-init-faces-h)
|
||||
|
||||
;; `highlight-indent-guides' breaks when `org-indent-mode' is active
|
||||
(add-hook! 'org-indent-mode-hook
|
||||
(defun +indent-guides-disable-maybe-h ()
|
||||
(when highlight-indent-guides-mode
|
||||
(highlight-indent-guides-mode -1)))))
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; ui/indent-guides/packages.el
|
||||
|
||||
(package! highlight-indent-guides)
|
||||
(package! highlight-indent-guides :pin "1b12c7b440ff988c7237936187c1375ac4ddc7f4")
|
||||
|
||||
@@ -50,17 +50,17 @@ side of the modeline, and whose CDR is the right-hand side.")
|
||||
;;
|
||||
;;; Faces
|
||||
|
||||
(defface +modeline-bar '((t (:inherit highlight)))
|
||||
(defface doom-modeline-bar '((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)))
|
||||
(defface doom-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
|
||||
(defface doom-modeline-highlight
|
||||
'((t (:inherit mode-line-highlight)))
|
||||
"Face used for highlighted modeline panels (like search counts).")
|
||||
|
||||
(defface +modeline-alternate-highlight
|
||||
(defface doom-modeline-alternate-highlight
|
||||
'((t (:inherit mode-line-highlight)))
|
||||
"Alternative face used for highlighted modeline panels (like search counts).")
|
||||
|
||||
@@ -68,14 +68,6 @@ side of the modeline, and whose CDR is the right-hand side.")
|
||||
;;
|
||||
;;; Helpers
|
||||
|
||||
(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)))
|
||||
|
||||
;;; `active'
|
||||
(defvar +modeline--active-window (selected-window))
|
||||
|
||||
@@ -144,19 +136,20 @@ If DEFAULT is non-nil, apply to all future buffers. Modelines are defined with
|
||||
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))))
|
||||
|
||||
(defmacro def-modeline! (name lhs rhs)
|
||||
(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."
|
||||
`(progn
|
||||
(setf (alist-get ',name +modeline-format-alist)
|
||||
(cons ,lhs ,rhs))
|
||||
(defun ,(intern (format "+modeline-set-%s-format-h" name)) (&rest _)
|
||||
"TODO"
|
||||
(set-modeline! ',name))))
|
||||
(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"
|
||||
@@ -182,178 +175,177 @@ LHS and RHS will accept."
|
||||
|
||||
|
||||
;;; `+modeline-bar'
|
||||
(progn
|
||||
(def-modeline-var! +modeline-bar "")
|
||||
(def-modeline-var! +modeline-inactive-bar "")
|
||||
(def-modeline-var! +modeline-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 nil 'inherit))
|
||||
width height)
|
||||
+modeline-inactive-bar
|
||||
(+modeline--make-xpm
|
||||
(and +modeline-bar-width
|
||||
(face-background '+modeline-bar-inactive nil 'inherit))
|
||||
width height)))))
|
||||
(defvar +modeline-active-bar "")
|
||||
(defvar +modeline-inactive-bar "")
|
||||
|
||||
(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))))))
|
||||
(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))
|
||||
(active-bg (face-background 'doom-modeline-bar nil t))
|
||||
(inactive-bg (face-background 'doom-modeline-bar-inactive nil t)))
|
||||
(when (or (null +modeline-bar-width)
|
||||
(= +modeline-bar-width 0))
|
||||
(setq active-bg nil
|
||||
inactive-bg nil))
|
||||
(setq +modeline-active-bar
|
||||
(+modeline--make-xpm (and +modeline-bar-width active-bg)
|
||||
width height)
|
||||
+modeline-inactive-bar
|
||||
(+modeline--make-xpm (and +modeline-bar-width inactive-bg)
|
||||
width height)
|
||||
+modeline-bar
|
||||
'(:eval (if (+modeline-active)
|
||||
+modeline-active-bar
|
||||
+modeline-inactive-bar))))))
|
||||
|
||||
(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))
|
||||
(use-package! anzu
|
||||
:after-call isearch-mode
|
||||
:config
|
||||
;; We manage our own modeline segments
|
||||
(setq anzu-cons-mode-line-p nil)
|
||||
;; Ensure anzu state is cleared when searches & iedit are done
|
||||
(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)))
|
||||
|
||||
(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
|
||||
:config (global-anzu-mode +1))
|
||||
|
||||
(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.
|
||||
(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))))
|
||||
(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 " (1+ here) total))
|
||||
(anzu--overflow-p
|
||||
(format " %s+ " total))
|
||||
(t
|
||||
(format " %s/%d " here total))))
|
||||
'face (if (+modeline-active) 'doom-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--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) 'doom-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--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 'doom-modeline-highlight)
|
||||
('doom-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--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--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) 'doom-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))))
|
||||
(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 'doom-modeline-highlight)))
|
||||
(concat sep
|
||||
(propertize (if (bound-and-true-p evil-this-macro)
|
||||
(char-to-string evil-this-macro)
|
||||
"Macro")
|
||||
'face 'doom-modeline-highlight)
|
||||
sep
|
||||
(all-the-icons-octicon "triangle-right"
|
||||
:face 'doom-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 ")))))
|
||||
(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)
|
||||
face bold
|
||||
mouse-face doom-modeline-highlight)
|
||||
mode-line-process
|
||||
"%n"
|
||||
" "))
|
||||
@@ -382,103 +374,104 @@ Requires `anzu', also `evil-anzu' if using `evil-mode' for compatibility with
|
||||
|
||||
|
||||
;;; `+modeline-checker'
|
||||
(progn
|
||||
(def-modeline-var! +modeline-checker nil
|
||||
"Displays color-coded error status & icon for the current buffer."
|
||||
:local t)
|
||||
(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")))))))
|
||||
(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)))
|
||||
(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
|
||||
(def-modeline-var! +modeline-selection-info
|
||||
'(:eval
|
||||
(when (or (and (bound-and-true-p evil-local-mode)
|
||||
(eq evil-state 'visual))
|
||||
mark-active)
|
||||
(cl-destructuring-bind (beg . end)
|
||||
(if (bound-and-true-p evil-visual-selection)
|
||||
(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))
|
||||
(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)))
|
||||
(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 (pcase (coding-system-eol-type buffer-file-coding-system)
|
||||
(0 " LF ")
|
||||
(1 " RLF ")
|
||||
(2 " CR "))
|
||||
(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)))))
|
||||
" ")))
|
||||
(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 "??")
|
||||
|
||||
|
||||
;;
|
||||
@@ -490,33 +483,35 @@ lines are selected, or the NxM dimensions of a block selection.")
|
||||
" "
|
||||
+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
|
||||
(def-modeline! 'project
|
||||
`(" "
|
||||
,(all-the-icons-octicon
|
||||
"file-directory"
|
||||
:face 'bold
|
||||
:v-adjust -0.05
|
||||
:height 1.25)
|
||||
:v-adjust -0.06
|
||||
:height 1.1)
|
||||
(:propertize (" " (:eval (abbreviate-file-name default-directory)))
|
||||
face bold))
|
||||
'("" +modeline-modes))
|
||||
'("" mode-line-misc-info +modeline-modes))
|
||||
|
||||
(def-modeline! special
|
||||
(def-modeline! 'special
|
||||
'("" +modeline-matches
|
||||
" " +modeline-buffer-identification)
|
||||
'("" +modeline-modes))
|
||||
|
||||
;; TODO (def-modeline! pdf ...)
|
||||
;; (def-modeline! pdf
|
||||
;; '("" +modeline-matches))
|
||||
;; TODO (def-modeline! helm ...)
|
||||
|
||||
|
||||
@@ -545,7 +540,7 @@ lines are selected, or the NxM dimensions of a block selection.")
|
||||
;; 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! 'pdf-tools-enabled-hook 'pdf)
|
||||
(set-modeline-hook! '(special-mode-hook
|
||||
image-mode-hook
|
||||
circe-mode-hook)
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
- [[#troubleshooting][Troubleshooting]]
|
||||
- [[#where-are-my-minor-modes][Where are my minor modes?]]
|
||||
- [[#icons-in-my-modeline-look-strange][Icons in my modeline look strange]]
|
||||
- [[#the-right-side-of-the-modeline-is-cut-off][The right side of the modeline is cut off]]
|
||||
- [[#appendix][Appendix]]
|
||||
- [[#autodefs][Autodefs]]
|
||||
- [[#variables][Variables]]
|
||||
@@ -30,7 +31,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]]
|
||||
@@ -62,6 +64,31 @@ I rarely need to know what minor modes are active, so I removed them. ~M-x
|
||||
doom/describe-active-minor-mode~ was written to substitute for it.
|
||||
|
||||
** TODO Icons in my modeline look strange
|
||||
** TODO The right side of the modeline is cut off
|
||||
I believe the consensus is: this is due to oversized icons, i.e. a font issue. Some possible solutions:
|
||||
|
||||
1. Tweak ~all-the-icons-scale-factor~ (1.2 by default): ~(setq
|
||||
all-the-icons-scale-factor 1.1)~
|
||||
|
||||
2. Add some padding to the modeline definition:
|
||||
|
||||
#+BEGIN_SRC elisp
|
||||
(after! doom-modeline
|
||||
(doom-modeline-def-modeline 'main
|
||||
'(bar matches buffer-info remote-host buffer-position parrot selection-info)
|
||||
'(misc-info minor-modes checker input-method buffer-encoding major-mode process vcs " "))) ; <-- added padding here
|
||||
#+END_SRC
|
||||
|
||||
3. Use another font for the mode line (or a different ~:height~) (source)
|
||||
|
||||
#+BEGIN_SRC elisp
|
||||
(custom-set-faces!
|
||||
'(mode-line :family "Noto Sans" :height 0.9)
|
||||
'(mode-line-inactive :family "Noto Sans" :height 0.9))
|
||||
#+END_SRC
|
||||
|
||||
(Mentioned in #1680, #278 and seagle0128/doom-modeline#334)
|
||||
|
||||
|
||||
* Appendix
|
||||
** Autodefs
|
||||
|
||||
@@ -1,15 +1,5 @@
|
||||
;;; ui/modeline/autoload/modeline.el -*- lexical-binding: t; -*-
|
||||
|
||||
;;;###autodef
|
||||
(defalias 'def-modeline-format! #'doom-modeline-def-modeline)
|
||||
|
||||
;;;###autodef
|
||||
(defalias 'def-modeline-segment! #'doom-modeline-def-segment)
|
||||
|
||||
;;;###autodef
|
||||
(defalias 'set-modeline! #'doom-modeline-set-modeline)
|
||||
|
||||
|
||||
(defvar +modeline--old-bar-height nil)
|
||||
;;;###autoload
|
||||
(defun +modeline-resize-for-font-h ()
|
||||
@@ -21,28 +11,26 @@ 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 _)
|
||||
"Update version strings in all buffers."
|
||||
(dolist (window (window-list))
|
||||
(with-selected-window window
|
||||
(doom-modeline-update-env)
|
||||
(when (fboundp 'doom-modeline-update-env)
|
||||
(doom-modeline-update-env))
|
||||
(force-mode-line-update))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +modeline-clear-env-in-all-windows-h (&rest _)
|
||||
"Blank out version strings in all buffers."
|
||||
(dolist (buffer (buffer-list))
|
||||
(with-current-buffer buffer
|
||||
(setq doom-modeline-env--version
|
||||
(bound-and-true-p doom-modeline-load-string))))
|
||||
(unless (featurep! +light)
|
||||
(dolist (buffer (buffer-list))
|
||||
(with-current-buffer buffer
|
||||
(setq doom-modeline-env--version
|
||||
(bound-and-true-p doom-modeline-load-string)))))
|
||||
(force-mode-line-update t))
|
||||
|
||||
@@ -4,9 +4,20 @@
|
||||
(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)
|
||||
:hook (doom-modeline-mode . size-indication-mode) ; filesize in modeline
|
||||
:hook (doom-modeline-mode . column-number-mode) ; cursor column in modeline
|
||||
:init
|
||||
(unless after-init-time
|
||||
;; prevent flash of unstyled modeline at startup
|
||||
@@ -34,10 +45,7 @@
|
||||
(defvar mouse-wheel-down-event nil)
|
||||
(defvar mouse-wheel-up-event nil)
|
||||
|
||||
(size-indication-mode +1) ; filesize in modeline
|
||||
(column-number-mode +1) ; cursor column in modeline
|
||||
|
||||
(add-hook 'doom-change-font-size-hook #'+modeline-resize-for-font-h)
|
||||
(add-hook 'after-setting-font-hook #'+modeline-resize-for-font-h)
|
||||
(add-hook 'doom-load-theme-hook #'doom-modeline-refresh-bars)
|
||||
|
||||
(add-hook '+doom-dashboard-mode-hook #'doom-modeline-set-project-modeline)
|
||||
@@ -46,22 +54,9 @@
|
||||
(defun +modeline-hide-in-non-status-buffer-h ()
|
||||
"Show minimal modeline in magit-status buffer, no modeline elsewhere."
|
||||
(if (eq major-mode 'magit-status-mode)
|
||||
(doom-modeline-set-project-modeline)
|
||||
(doom-modeline-set-vcs-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-buffers 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)
|
||||
@@ -76,4 +71,5 @@
|
||||
|
||||
(use-package! evil-anzu
|
||||
:when (featurep! :editor evil)
|
||||
:after-call evil-ex-start-search evil-ex-start-word-search evil-ex-search-activate-highlight))
|
||||
:after-call evil-ex-start-search evil-ex-start-word-search evil-ex-search-activate-highlight
|
||||
:config (global-anzu-mode +1)))
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
;;; ui/modeline/packages.el
|
||||
|
||||
(unless (featurep! +light)
|
||||
(package! doom-modeline))
|
||||
(package! anzu)
|
||||
(package! doom-modeline :pin "2b308857677e983ca4eaedc36438ed94aadf9e65"))
|
||||
(package! anzu :pin "7b8688c84d6032300d0c415182c7c1ad6cb7f819")
|
||||
(when (featurep! :editor evil)
|
||||
(package! evil-anzu))
|
||||
(package! evil-anzu :pin "d3f6ed4773b48767bd5f4708c7f083336a8a8a86"))
|
||||
|
||||
@@ -5,6 +5,10 @@
|
||||
org-find-file org-find-file-at-mouse)
|
||||
"A list of commands that should not trigger nav-flash.")
|
||||
|
||||
|
||||
;;
|
||||
;;; Packages
|
||||
|
||||
(use-package! nav-flash
|
||||
:defer t
|
||||
:init
|
||||
@@ -30,4 +34,8 @@
|
||||
(advice-add #'evil-window-bottom :after #'+nav-flash-blink-cursor-a)
|
||||
|
||||
;; Bound to `ga' for evil users
|
||||
(advice-add #'what-cursor-position :after #'+nav-flash-blink-cursor-a))
|
||||
(advice-add #'what-cursor-position :after #'+nav-flash-blink-cursor-a)
|
||||
|
||||
:config
|
||||
(when (fboundp 'set-face-extend)
|
||||
(set-face-extend 'nav-flash-face t)))
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; ui/nav-flash/packages.el
|
||||
|
||||
(package! nav-flash)
|
||||
(package! nav-flash :pin "dbb91216637e0a1e8bfd59aa883c75d45db70daf")
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -8,12 +8,12 @@
|
||||
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 'icons
|
||||
neo-banner-message nil
|
||||
@@ -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 "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
|
||||
: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 [tab] (neotree-make-executor
|
||||
:dir-fn #'neo-open-dir
|
||||
:file-fn #'neotree-quick-look)
|
||||
:n "DEL" #'evil-window-prev
|
||||
:n "n" #'neotree-next-line
|
||||
:n "p" #'neotree-previous-line
|
||||
: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-make-executor :file-fn 'neo-open-file-vertical-split)
|
||||
:n "s" (neotree-make-executor :file-fn 'neo-open-file-horizontal-split)))
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; ui/neotree/packages.el
|
||||
|
||||
(package! neotree)
|
||||
(package! neotree :pin "5e1271655170f4cdc6849258e383c548a4e6e3d0")
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
(use-package! evil-goggles
|
||||
:when (featurep! :editor evil)
|
||||
:after-call pre-command-hook
|
||||
:hook (doom-first-input . evil-goggles-mode)
|
||||
:init
|
||||
(setq evil-goggles-duration 0.1
|
||||
evil-goggles-pulse nil ; too slow
|
||||
@@ -12,6 +12,10 @@
|
||||
evil-goggles-enable-change nil)
|
||||
:config
|
||||
(pushnew! evil-goggles--commands
|
||||
'(evil-magit-yank-whole-line
|
||||
:face evil-goggles-yank-face
|
||||
:switch evil-goggles-enable-yank
|
||||
:advice evil-goggles--generic-async-advice)
|
||||
'(+evil:yank-unindented
|
||||
:face evil-goggles-yank-face
|
||||
:switch evil-goggles-enable-yank
|
||||
@@ -19,15 +23,13 @@
|
||||
'(+eval:region
|
||||
:face evil-goggles-yank-face
|
||||
:switch evil-goggles-enable-yank
|
||||
:advice evil-goggles--generic-async-advice))
|
||||
(evil-goggles-mode +1))
|
||||
:advice evil-goggles--generic-async-advice)))
|
||||
|
||||
|
||||
(use-package! volatile-highlights
|
||||
:unless (featurep! :editor evil)
|
||||
:after-call pre-command-hook
|
||||
:hook (doom-first-input . volatile-highlights-mode)
|
||||
:config
|
||||
(volatile-highlights-mode)
|
||||
(after! undo-tree
|
||||
(vhl/define-extension 'undo-tree 'undo-tree-yank 'undo-tree-move)
|
||||
(vhl/install-extension 'undo-tree)))
|
||||
(after! undo-fu
|
||||
(vhl/define-extension 'undo-fu 'undo-fu-only-undo 'undo-fu-only-redo)
|
||||
(vhl/install-extension 'undo-fu)))
|
||||
|
||||
@@ -2,5 +2,5 @@
|
||||
;;; ui/ophints/packages.el
|
||||
|
||||
(if (featurep! :editor evil)
|
||||
(package! evil-goggles)
|
||||
(package! volatile-highlights))
|
||||
(package! evil-goggles :pin "08a22058fd6a167f9f1b684c649008caef571459")
|
||||
(package! volatile-highlights :pin "9a20091f0ce7fc0a6b3e641a6a46d5f3ac4d8392"))
|
||||
|
||||
@@ -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).
|
||||
@@ -26,6 +26,15 @@
|
||||
;;
|
||||
;;; Core functions
|
||||
|
||||
(defadvice! +popup--make-case-sensitive-a (orig-fn &rest args)
|
||||
"Make regexps in `display-buffer-alist' case-sensitive.
|
||||
|
||||
To reduce fewer edge cases and improve performance when `display-buffer-alist'
|
||||
grows larger."
|
||||
:around #'display-buffer-assq-regexp
|
||||
(let (case-fold-search)
|
||||
(apply orig-fn args)))
|
||||
|
||||
;; Don't try to resize popup windows
|
||||
(advice-add #'balance-windows :around #'+popup-save-a)
|
||||
|
||||
@@ -37,8 +46,8 @@ to this commmand."
|
||||
(let ((orig-buffer (current-buffer)))
|
||||
(quit-window)
|
||||
(when (and (eq orig-buffer (current-buffer))
|
||||
(+popup-window-p))
|
||||
(+popup/close))))
|
||||
(+popup-buffer-p))
|
||||
(+popup/close nil 'force))))
|
||||
(global-set-key [remap quit-window] #'+popup/quit-window)
|
||||
|
||||
|
||||
@@ -186,30 +195,28 @@ the command buffer."
|
||||
;; Fix #897: "cannot open side window" error when TAB-completing file links
|
||||
(defadvice! +popup--helm-hide-org-links-popup-a (orig-fn &rest args)
|
||||
:around #'org-insert-link
|
||||
(cl-letf* ((old-org-completing-read (symbol-function 'org-completing-read))
|
||||
((symbol-function 'org-completing-read)
|
||||
(lambda (&rest args)
|
||||
(when-let (win (get-buffer-window "*Org Links*"))
|
||||
;; While helm is opened as a popup, it will mistaken the
|
||||
;; *Org Links* popup for the "originated window", and will
|
||||
;; target it for actions invoked by the user. However, since
|
||||
;; *Org Links* is a popup too (they're dedicated side
|
||||
;; windows), Emacs complains about being unable to split a
|
||||
;; side window. The simple fix: get rid of *Org Links*!
|
||||
(delete-window win)
|
||||
;; But it must exist for org to clean up later.
|
||||
(get-buffer-create "*Org Links*"))
|
||||
(apply old-org-completing-read args))))
|
||||
(letf! ((defun org-completing-read (&rest args)
|
||||
(when-let (win (get-buffer-window "*Org Links*"))
|
||||
;; While helm is opened as a popup, it will mistaken the *Org
|
||||
;; Links* popup for the "originated window", and will target it
|
||||
;; for actions invoked by the user. However, since *Org Links*
|
||||
;; is a popup too (they're dedicated side windows), Emacs
|
||||
;; complains about being unable to split a side window. The
|
||||
;; simple fix: get rid of *Org Links*!
|
||||
(delete-window win)
|
||||
;; ...but it must exist for org to clean up later.
|
||||
(get-buffer-create "*Org Links*"))
|
||||
(apply org-completing-read args)))
|
||||
(apply #'funcall-interactively orig-fn args)))
|
||||
|
||||
;; Fix left-over popup window when closing persistent help for `helm-M-x'
|
||||
(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)))))
|
||||
(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
|
||||
@@ -219,32 +226,37 @@ the command buffer."
|
||||
(when (+popup-window-p win)
|
||||
(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
|
||||
;; kills all other windows just so it can monopolize the frame. No thanks. We
|
||||
;; can do better ourselves.
|
||||
;; can do better.
|
||||
(defadvice! +popup--suppress-delete-other-windows-a (orig-fn &rest args)
|
||||
:around '(org-add-log-note
|
||||
org-capture-place-template
|
||||
org-export--dispatch-ui
|
||||
org-agenda-get-restriction-and-command
|
||||
org-goto-location
|
||||
org-fast-tag-selection
|
||||
org-fast-todo-selection)
|
||||
(if +popup-mode
|
||||
(cl-letf (((symbol-function #'delete-other-windows)
|
||||
(symbol-function #'ignore)))
|
||||
(letf! ((#'delete-other-windows #'ignore)
|
||||
(#'delete-window #'ignore))
|
||||
(apply orig-fn args))
|
||||
(apply orig-fn args)))
|
||||
|
||||
(defadvice! +popup--org-fix-goto-a (orig-fn &rest args)
|
||||
"`org-goto' uses `with-output-to-temp-buffer' to display its help buffer,
|
||||
for some reason, which is very unconventional, and so requires these gymnastics
|
||||
to tame (i.e. to get the popup manager to handle it)."
|
||||
:around #'org-goto-location
|
||||
(if +popup-mode
|
||||
(letf! (defun internal-temp-output-buffer-show (buffer)
|
||||
(let ((temp-buffer-show-function
|
||||
(doom-rpartial #'+popup-display-buffer-stacked-side-window-fn nil)))
|
||||
(with-current-buffer buffer
|
||||
(hide-mode-line-mode +1))
|
||||
(funcall internal-temp-output-buffer-show buffer)))
|
||||
(apply orig-fn args))
|
||||
(apply orig-fn args)))
|
||||
|
||||
@@ -255,16 +267,14 @@ Ugh, such an ugly hack."
|
||||
:around '(org-fast-tag-selection
|
||||
org-fast-todo-selection)
|
||||
(if +popup-mode
|
||||
(cl-letf* ((old-fit-buffer-fn (symbol-function #'org-fit-window-to-buffer))
|
||||
((symbol-function #'org-fit-window-to-buffer)
|
||||
(lambda (&optional window max-height min-height shrink-only)
|
||||
(when-let (buf (window-buffer window))
|
||||
(delete-window window)
|
||||
(select-window
|
||||
(setq window (display-buffer-at-bottom buf nil)))
|
||||
(with-current-buffer buf
|
||||
(setq mode-line-format nil)))
|
||||
(funcall old-fit-buffer-fn window max-height min-height shrink-only))))
|
||||
(letf! ((defun org-fit-window-to-buffer (&optional window max-height min-height shrink-only)
|
||||
(when-let (buf (window-buffer window))
|
||||
(delete-window window)
|
||||
(select-window
|
||||
(setq window (display-buffer-at-bottom buf nil)))
|
||||
(with-current-buffer buf
|
||||
(setq mode-line-format nil)))
|
||||
(funcall org-fit-window-to-buffer window max-height min-height shrink-only)))
|
||||
(apply orig-fn args))
|
||||
(apply orig-fn args)))
|
||||
|
||||
@@ -274,7 +284,24 @@ 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
|
||||
(letf! ((#'pop-to-buffer-same-window #'switch-to-buffer))
|
||||
(apply orig-fn args))))
|
||||
|
||||
|
||||
;;;###package org-journal
|
||||
(defadvice! +popup--use-popup-window-a (orig-fn &rest args)
|
||||
:around #'org-journal-search-by-string
|
||||
(letf! ((#'switch-to-buffer #'pop-to-buffer))
|
||||
(apply orig-fn args)))
|
||||
|
||||
|
||||
;;;###package persp-mode
|
||||
@@ -304,8 +331,7 @@ Ugh, such an ugly hack."
|
||||
;;;###package profiler
|
||||
(defadvice! +popup--profiler-report-find-entry-in-other-window-a (orig-fn function)
|
||||
:around #'profiler-report-find-entry
|
||||
(cl-letf (((symbol-function 'find-function)
|
||||
(symbol-function 'find-function-other-window)))
|
||||
(letf! ((#'find-function #'find-function-other-window))
|
||||
(funcall orig-fn function)))
|
||||
|
||||
|
||||
@@ -320,14 +346,16 @@ 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)
|
||||
(cl-letf (((symbol-function 'display-buffer-in-side-window)
|
||||
(lambda (buffer alist)
|
||||
(+popup-display-buffer-stacked-side-window-fn
|
||||
buffer (append '((vslot . -9999)) alist)))))
|
||||
(letf! ((defun display-buffer-in-side-window (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))))))
|
||||
|
||||
|
||||
@@ -336,9 +364,8 @@ Ugh, such an ugly hack."
|
||||
(defadvice! +popup--ignore-window-parameters-a (orig-fn &rest args)
|
||||
"Allow *interactive* window moving commands to traverse popups."
|
||||
:around '(windmove-up windmove-down windmove-left windmove-right)
|
||||
(cl-letf (((symbol-function #'windmove-find-other-window)
|
||||
(lambda (dir &optional arg window)
|
||||
(window-in-direction
|
||||
(pcase dir (`up 'above) (`down 'below) (_ dir))
|
||||
window (bound-and-true-p +popup-mode) arg windmove-wrap-around t))))
|
||||
(letf! ((defun windmove-find-other-window (dir &optional arg window)
|
||||
(window-in-direction
|
||||
(pcase dir (`up 'above) (`down 'below) (_ dir))
|
||||
window (bound-and-true-p +popup-mode) arg windmove-wrap-around t)))
|
||||
(apply orig-fn args)))
|
||||
|
||||
@@ -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.
|
||||
@@ -180,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
|
||||
@@ -393,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))
|
||||
@@ -415,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)
|
||||
@@ -428,19 +429,21 @@ 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 ()
|
||||
"Reveal what popup rule will be used for the current buffer."
|
||||
(interactive)
|
||||
(or (cl-loop with bname = (buffer-name)
|
||||
for (pred . action) in display-buffer-alist
|
||||
if (and (functionp pred) (funcall pred bname action))
|
||||
return (cons pred action)
|
||||
else if (and (stringp pred) (string-match-p pred bname))
|
||||
return (cons pred action))
|
||||
(message "No popup rule for this buffer")))
|
||||
(if-let (rule (cl-loop with bname = (buffer-name)
|
||||
for (pred . action) in display-buffer-alist
|
||||
if (and (functionp pred) (funcall pred bname action))
|
||||
return (cons pred action)
|
||||
else if (and (stringp pred) (string-match-p pred bname))
|
||||
return (cons pred action)))
|
||||
(message "Rule matches: %s" rule)
|
||||
(message "No popup rule for this buffer")))
|
||||
|
||||
|
||||
;;
|
||||
|
||||
@@ -68,7 +68,7 @@ PLIST can be made up of any of the following properties:
|
||||
is in :actions or `+popup-default-display-buffer-actions'.
|
||||
|
||||
:size/:width/:height FLOAT|INT|FN
|
||||
Determines the size of the popup. If more tha one of these size properties are
|
||||
Determines the size of the popup. If more than one of these size properties are
|
||||
given :size always takes precedence, and is mapped with window-width or
|
||||
window-height depending on what :side the popup is opened. Setting a height
|
||||
for a popup that opens on the left or right is harmless, but comes into play
|
||||
|
||||
@@ -110,6 +110,7 @@ prevent the popup(s) from messing up the UI (or vice versa)."
|
||||
`(let* ((in-popup-p (+popup-buffer-p))
|
||||
(popups (+popup-windows))
|
||||
(+popup--inhibit-transient t)
|
||||
buffer-list-update-hook
|
||||
+popup--last)
|
||||
(dolist (p popups)
|
||||
(+popup/close p 'force))
|
||||
@@ -131,20 +132,22 @@ 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)
|
||||
("^\\*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"
|
||||
:vslot -7 :side bottom :size 0.4 :select t :quit nil :ttl 0)
|
||||
("^\\*Customize"
|
||||
:slot 2 :side right :select t :quit t)
|
||||
:slot 2 :side right :size 0.5 :select t :quit nil)
|
||||
("^ \\*undo-tree\\*"
|
||||
:slot 2 :side left :size 20 :select t :quit t)
|
||||
;; `help-mode', `helpful-mode'
|
||||
|
||||
@@ -110,10 +110,15 @@
|
||||
("~>" . #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)
|
||||
(set-fontset-font t '(#Xe100 . #Xe16f) +pretty-code-fira-code-font-name nil 'prepend)
|
||||
(setq-default prettify-symbols-alist
|
||||
(append prettify-symbols-alist
|
||||
(mapcar #'+pretty-code--correct-symbol-bounds
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
|
||||
|
||||
(defun +pretty-code-setup-hasklig-ligatures-h ()
|
||||
(set-fontset-font t '(#Xe100 . #Xe129) +pretty-code-hasklig-font-name)
|
||||
(set-fontset-font t '(#Xe100 . #Xe129) +pretty-code-hasklig-font-name nil 'prepend)
|
||||
(setq-default prettify-symbols-alist
|
||||
(append prettify-symbols-alist
|
||||
(mapcar #'+pretty-code--correct-symbol-bounds
|
||||
|
||||
@@ -224,7 +224,7 @@
|
||||
"Defines the character mappings for ligatures for Iosevka.")
|
||||
|
||||
(defun +pretty-code-setup-iosevka-ligatures-h ()
|
||||
(set-fontset-font t '(#Xe100 . #Xe1cc) +pretty-code-iosevka-font-name)
|
||||
(set-fontset-font t '(#Xe100 . #Xe1cc) +pretty-code-iosevka-font-name nil 'prepend)
|
||||
(setq-default prettify-symbols-alist
|
||||
(append prettify-symbols-alist
|
||||
+pretty-code-iosevka-font-ligatures)))
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
;;; ui/pretty-code/settings.el -*- lexical-binding: t; -*-
|
||||
|
||||
;;;###autoload
|
||||
(defvar +pretty-code-symbols-alist '((t))
|
||||
"An alist containing a mapping of major modes to its value for
|
||||
`prettify-symbols-alist'.")
|
||||
|
||||
;;;###autodef
|
||||
(defun set-pretty-symbols! (modes &rest plist)
|
||||
"Associates string patterns with icons in certain major-modes.
|
||||
|
||||
MODES is a major mode symbol or a list of them.
|
||||
PLIST is a property list whose keys must match keys in `+pretty-code-symbols',
|
||||
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:
|
||||
|
||||
: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:
|
||||
|
||||
(set-pretty-symbols! 'emacs-lisp-mode
|
||||
:lambda \"lambda\")
|
||||
|
||||
This will replace any instances of \"lambda\" in emacs-lisp-mode with the symbol
|
||||
assicated with :lambda in `+pretty-code-symbols'.
|
||||
|
||||
Pretty symbols can be unset for emacs-lisp-mode with:
|
||||
|
||||
(set-pretty-symbols! 'emacs-lisp-mode nil)"
|
||||
(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)
|
||||
(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)))))
|
||||
(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)))))
|
||||
@@ -5,6 +5,8 @@
|
||||
:name "»"
|
||||
:src_block "»"
|
||||
:src_block_end "«"
|
||||
:quote "“"
|
||||
:quote_end "”"
|
||||
;; Functional
|
||||
:lambda "λ"
|
||||
:def "ƒ"
|
||||
@@ -18,6 +20,7 @@
|
||||
:float "ℝ"
|
||||
:str "𝕊"
|
||||
:bool "𝔹"
|
||||
:list "𝕃"
|
||||
;; Flow
|
||||
:not "¬"
|
||||
:in "∈"
|
||||
@@ -29,6 +32,9 @@
|
||||
:return "⟼"
|
||||
:yield "⟻"
|
||||
;; Other
|
||||
:union "⋃"
|
||||
:intersect "∩"
|
||||
:diff "∖"
|
||||
:tuple "⨂"
|
||||
:pipe "" ;; FIXME: find a non-private char
|
||||
:dot "•")
|
||||
@@ -38,6 +44,65 @@ This should not contain any symbols from the Unicode Private Area! There is no
|
||||
universal way of getting the correct symbol as that area varies from font to
|
||||
font.")
|
||||
|
||||
(defvar +pretty-code-enabled-modes t
|
||||
"List of major modes in which `prettify-symbols-mode' should be enabled.
|
||||
If t, enable it everywhere. If the first element is 'not, enable it in any mode
|
||||
besides what is listed.")
|
||||
|
||||
(defvar +pretty-code-symbols-alist '((t))
|
||||
"An alist containing a mapping of major modes to its value for
|
||||
`prettify-symbols-alist'.")
|
||||
|
||||
;;; Automatic font-specific ligatures
|
||||
(defvar +prog-ligatures-alist
|
||||
'((?! . "\\(?:!\\(?:==\\|[!=]\\)\\)") ; (regexp-opt '("!!" "!=" "!=="))
|
||||
(?# . "\\(?:#\\(?:###?\\|_(\\|[#(:=?[_{]\\)\\)") ; (regexp-opt '("##" "###" "####" "#(" "#:" "#=" "#?" "#[" "#_" "#_(" "#{"))
|
||||
(?$ . "\\(?:\\$>>?\\)") ; (regexp-opt '("$>" "$>>"))
|
||||
(?% . "\\(?:%%%?\\)") ; (regexp-opt '("%%" "%%%"))
|
||||
(?& . "\\(?:&&&?\\)") ; (regexp-opt '("&&" "&&&"))
|
||||
(?* . "\\(?:\\*\\(?:\\*[*/]\\|[)*/>]\\)?\\)") ; (regexp-opt '("*" "**" "***" "**/" "*/" "*>" "*)"))
|
||||
(?+ . "\\(?:\\+\\(?:\\+\\+\\|[+:>]\\)?\\)") ; (regexp-opt '("+" "++" "+++" "+>" "+:"))
|
||||
(?- . "\\(?:-\\(?:-\\(?:->\\|[>-]\\)\\|<[<-]\\|>[>-]\\|[:<>|}~-]\\)\\)") ; (regexp-opt '("--" "---" "-->" "--->" "->-" "-<" "-<-" "-<<" "->" "->>" "-}" "-~" "-:" "-|"))
|
||||
(?. . "\\(?:\\.\\(?:\\.[.<]\\|[.=>-]\\)\\)") ; (regexp-opt '(".-" ".." "..." "..<" ".=" ".>"))
|
||||
(?/ . "\\(?:/\\(?:\\*\\*\\|//\\|==\\|[*/=>]\\)\\)") ; (regexp-opt '("/*" "/**" "//" "///" "/=" "/==" "/>"))
|
||||
(?: . "\\(?::\\(?:::\\|[+:<=>]\\)?\\)") ; (regexp-opt '(":" "::" ":::" ":=" ":<" ":=" ":>" ":+"))
|
||||
(?\; . ";;") ; (regexp-opt '(";;"))
|
||||
(?0 . "0\\(?:\\(x[a-fA-F0-9]\\).?\\)") ; Tries to match the x in 0xDEADBEEF
|
||||
;; (?x . "x") ; Also tries to match the x in 0xDEADBEEF
|
||||
;; (regexp-opt '("<!--" "<$" "<$>" "<*" "<*>" "<**>" "<+" "<+>" "<-" "<--" "<---" "<->" "<-->" "<--->" "</" "</>" "<<" "<<-" "<<<" "<<=" "<=" "<=<" "<==" "<=>" "<===>" "<>" "<|" "<|>" "<~" "<~~" "<." "<.>" "<..>"))
|
||||
(?< . "\\(?:<\\(?:!--\\|\\$>\\|\\*\\(?:\\*?>\\)\\|\\+>\\|-\\(?:-\\(?:->\\|[>-]\\)\\|[>-]\\)\\|\\.\\(?:\\.?>\\)\\|/>\\|<[<=-]\\|=\\(?:==>\\|[<=>]\\)\\||>\\|~~\\|[$*+./<=>|~-]\\)\\)")
|
||||
(?= . "\\(?:=\\(?:/=\\|:=\\|<<\\|=[=>]\\|>>\\|[=>]\\)\\)") ; (regexp-opt '("=/=" "=:=" "=<<" "==" "===" "==>" "=>" "=>>"))
|
||||
(?> . "\\(?:>\\(?:->\\|=>\\|>[=>-]\\|[:=>-]\\)\\)") ; (regexp-opt '(">-" ">->" ">:" ">=" ">=>" ">>" ">>-" ">>=" ">>>"))
|
||||
(?? . "\\(?:\\?[.:=?]\\)") ; (regexp-opt '("??" "?." "?:" "?="))
|
||||
(?\[ . "\\(?:\\[\\(?:|]\\|[]|]\\)\\)") ; (regexp-opt '("[]" "[|]" "[|"))
|
||||
(?\\ . "\\(?:\\\\\\\\[\\n]?\\)") ; (regexp-opt '("\\\\" "\\\\\\" "\\\\n"))
|
||||
(?^ . "\\(?:\\^==?\\)") ; (regexp-opt '("^=" "^=="))
|
||||
(?w . "\\(?:wwww?\\)") ; (regexp-opt '("www" "wwww"))
|
||||
(?{ . "\\(?:{\\(?:|\\(?:|}\\|[|}]\\)\\|[|-]\\)\\)") ; (regexp-opt '("{-" "{|" "{||" "{|}" "{||}"))
|
||||
(?| . "\\(?:|\\(?:->\\|=>\\||=\\|[]=>|}-]\\)\\)") ; (regexp-opt '("|=" "|>" "||" "||=" "|->" "|=>" "|]" "|}" "|-"))
|
||||
(?_ . "\\(?:_\\(?:|?_\\)\\)") ; (regexp-opt '("_|_" "__"))
|
||||
(?\( . "\\(?:(\\*\\)") ; (regexp-opt '("(*"))
|
||||
(?~ . "\\(?:~\\(?:~>\\|[=>@~-]\\)\\)")) ; (regexp-opt '("~-" "~=" "~>" "~@" "~~" "~~>"))
|
||||
"An alist of all ligatures used by `+prog-ligatures-modes'.
|
||||
|
||||
The car is the character ASCII number, cdr is a regex which will call
|
||||
`font-shape-gstring' when matched.
|
||||
|
||||
Because of the underlying code in :ui pretty-code module, the regex should match
|
||||
a string starting with the character contained in car.
|
||||
|
||||
This variable is used only if you built Emacs with Harfbuzz on a version >= 28")
|
||||
|
||||
(defvar +prog-ligatures-modes '(not org-mode)
|
||||
"List of major modes in which ligatures should be enabled.
|
||||
|
||||
If t, enable it everywhere. Fundamental mode, and modes derived from special-mode,
|
||||
comint-mode, eshell-mode and term-mode are *still* excluded.
|
||||
|
||||
If the first element is 'not, enable it in any mode besides what is listed.
|
||||
|
||||
If nil, fallback to the prettify-symbols based replacement (add +font features to pretty-code).")
|
||||
|
||||
(defun +pretty-code--correct-symbol-bounds (ligature-alist)
|
||||
"Prepend non-breaking spaces to a ligature.
|
||||
|
||||
@@ -50,14 +115,6 @@ correct width of the symbols instead of the width measured by `char-width'."
|
||||
len (1- len)))
|
||||
(cons (car ligature-alist) acc)))
|
||||
|
||||
(defvar +pretty-code-enabled-modes t
|
||||
"List of major modes in which `prettify-symbols-mode' should be enabled.
|
||||
If t, enable it everywhere. If the first element is 'not, enable it in any mode
|
||||
besides what is listed.")
|
||||
|
||||
;; When you get to the right edge, it goes back to how it normally prints
|
||||
(setq prettify-symbols-unprettify-at-point 'right-edge)
|
||||
|
||||
(defun +pretty-code-init-pretty-symbols-h ()
|
||||
"Enable `prettify-symbols-mode'.
|
||||
|
||||
@@ -80,14 +137,63 @@ Otherwise it builds `prettify-code-symbols-alist' according to
|
||||
(prettify-symbols-mode -1))
|
||||
(prettify-symbols-mode +1))))
|
||||
|
||||
(defun +pretty-code-init-ligatures-h ()
|
||||
"Enable ligatures.
|
||||
|
||||
If in fundamental-mode, or a mode derived from special, comint, eshell or term
|
||||
modes, this function does nothing.
|
||||
|
||||
Otherwise it sets the buffer-local composition table to a composition table enhanced with
|
||||
`+prog-ligatures-alist' ligatures regexes."
|
||||
(unless (or (eq major-mode 'fundamental-mode)
|
||||
(eq (get major-mode 'mode-class) 'special)
|
||||
(derived-mode-p 'comint-mode 'eshell-mode 'term-mode))
|
||||
(when (or (eq +prog-ligatures-modes t)
|
||||
(if (eq (car +prog-ligatures-modes) 'not)
|
||||
(not (memq major-mode (cdr +prog-ligatures-modes)))
|
||||
(memq major-mode +prog-ligatures-modes)))
|
||||
(setq-local composition-function-table composition-ligature-table))))
|
||||
|
||||
|
||||
;;
|
||||
;;; Bootstrap
|
||||
|
||||
(add-hook 'after-change-major-mode-hook #'+pretty-code-init-pretty-symbols-h)
|
||||
|
||||
;; Font-specific ligature support
|
||||
(cond ((featurep! +fira)
|
||||
(load! "+fira"))
|
||||
((featurep! +iosevka)
|
||||
(load! "+iosevka"))
|
||||
((featurep! +hasklig)
|
||||
(load! "+hasklig"))
|
||||
((featurep! +pragmata-pro)
|
||||
(load! "+pragmata-pro")))
|
||||
;;;###package prettify-symbols
|
||||
;; When you get to the right edge, it goes back to how it normally prints
|
||||
(setq prettify-symbols-unprettify-at-point 'right-edge)
|
||||
|
||||
(cond
|
||||
;; The emacs-mac build of Emacs appear to have built-in support for ligatures,
|
||||
;; using the same composition-function-table method
|
||||
;; https://bitbucket.org/mituharu/emacs-mac/src/26c8fd9920db9d34ae8f78bceaec714230824dac/lisp/term/mac-win.el?at=master#lines-345:805
|
||||
;; so use that instead if this module is enabled.
|
||||
((and IS-MAC (fboundp 'mac-auto-operator-composition-mode))
|
||||
(mac-auto-operator-composition-mode))
|
||||
|
||||
;; Harfbuzz builds do not need font-specific ligature support
|
||||
;; if they are above emacs-27
|
||||
((and EMACS28+
|
||||
(string-match-p "HARFBUZZ" system-configuration-features)
|
||||
+prog-ligatures-modes
|
||||
(require 'composite nil t))
|
||||
(defvar composition-ligature-table (make-char-table nil))
|
||||
|
||||
(dolist (char-regexp +prog-ligatures-alist)
|
||||
(set-char-table-range composition-ligature-table (car char-regexp)
|
||||
`([,(cdr char-regexp) 0 font-shape-gstring])))
|
||||
(unless doom-reloading-p
|
||||
(set-char-table-parent composition-ligature-table composition-function-table))
|
||||
|
||||
(add-hook 'after-change-major-mode-hook #'+pretty-code-init-ligatures-h))
|
||||
|
||||
;; Font-specific ligature support
|
||||
((featurep! +fira)
|
||||
(load! "+fira"))
|
||||
((featurep! +iosevka)
|
||||
(load! "+iosevka"))
|
||||
((featurep! +hasklig)
|
||||
(load! "+hasklig"))
|
||||
((featurep! +pragmata-pro)
|
||||
(load! "+pragmata-pro")))
|
||||
|
||||
@@ -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))))
|
||||
@@ -1,71 +1,23 @@
|
||||
;;; ui/tabs/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
(use-package! centaur-tabs
|
||||
:after-call after-find-file dired-initial-position-hook
|
||||
:hook (doom-first-file . centaur-tabs-mode)
|
||||
: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 "⬤"
|
||||
;; Scrolling (with the mouse wheel) past the end of the tab list
|
||||
;; replaces the tab list with that of another Doom workspace. This
|
||||
;; prevents that.
|
||||
centaur-tabs-cycle-scope 'tabs)
|
||||
|
||||
: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)
|
||||
(add-hook '+popup-buffer-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)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; ui/tabs/packages.el
|
||||
|
||||
(package! centaur-tabs)
|
||||
(package! centaur-tabs :pin "2154fa9679c5fa02a2a7e3d4c739256fd991a789")
|
||||
|
||||
@@ -1,22 +1,5 @@
|
||||
;;; ui/treemacs/autoload.el -*- lexical-binding: t; -*-
|
||||
|
||||
(defun +treemacs--init ()
|
||||
(require 'treemacs)
|
||||
(let ((origin-buffer (current-buffer)))
|
||||
(cl-letf (((symbol-function 'treemacs-workspace->is-empty?)
|
||||
(symbol-function 'ignore)))
|
||||
(treemacs--init))
|
||||
(dolist (project (treemacs-workspace->projects (treemacs-current-workspace)))
|
||||
(treemacs-do-remove-project-from-workspace project))
|
||||
(with-current-buffer origin-buffer
|
||||
(let ((project-root (or (doom-project-root) default-directory)))
|
||||
(treemacs-do-add-project-to-workspace
|
||||
(treemacs--canonical-path project-root)
|
||||
(doom-project-name project-root)))
|
||||
(setq treemacs--ready-to-follow t)
|
||||
(when (or treemacs-follow-after-init treemacs-follow-mode)
|
||||
(treemacs--follow)))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +treemacs/toggle ()
|
||||
"Initialize or toggle treemacs.
|
||||
@@ -29,13 +12,6 @@ Use `treemacs' command for old functionality."
|
||||
(require 'treemacs)
|
||||
(pcase (treemacs-current-visibility)
|
||||
(`visible (delete-window (treemacs-get-local-window)))
|
||||
(_ (+treemacs--init))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +treemacs/find-file (arg)
|
||||
"Open treemacs (if necessary) and find current file."
|
||||
(interactive "P")
|
||||
(let ((origin-buffer (current-buffer)))
|
||||
(+treemacs--init)
|
||||
(with-current-buffer origin-buffer
|
||||
(treemacs-find-file arg))))
|
||||
(_ (if (doom-project-p)
|
||||
(treemacs-add-and-display-current-project)
|
||||
(treemacs)))))
|
||||
|
||||
@@ -1,25 +1,48 @@
|
||||
;;; ui/treemacs/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
(setq treemacs-follow-after-init t
|
||||
treemacs-is-never-other-window t
|
||||
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"))
|
||||
(defvar +treemacs-git-mode 'simple
|
||||
"Type of git integration for `treemacs-git-mode'.
|
||||
|
||||
There are 3 possible values:
|
||||
|
||||
1) `simple', which highlights only files based on their git status, and is
|
||||
slightly faster,
|
||||
2) `extended', which highlights both files and directories, but requires
|
||||
python,
|
||||
3) `deferred', same as extended, but highlights asynchronously.
|
||||
|
||||
This must be set before `treemacs' has loaded.")
|
||||
|
||||
|
||||
(after! treemacs
|
||||
(set-popup-rule! "^ \\*Treemacs"
|
||||
:side treemacs-position
|
||||
:size treemacs-width
|
||||
:quit nil
|
||||
:ttl 0)
|
||||
;;
|
||||
;;; Packages
|
||||
|
||||
(use-package! treemacs
|
||||
:defer t
|
||||
:init
|
||||
(setq treemacs-follow-after-init t
|
||||
treemacs-is-never-other-window t
|
||||
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"))
|
||||
:config
|
||||
;; Allow ace-window to target treemacs windows
|
||||
(after! ace-window
|
||||
(delq! 'treemacs-mode aw-ignored-buffers))
|
||||
|
||||
;; Don't follow the cursor
|
||||
(treemacs-follow-mode -1)
|
||||
|
||||
;; Allow ace-window to target treemacs windows
|
||||
(after! ace-window
|
||||
(delq! 'treemacs-mode aw-ignored-buffers)))
|
||||
(when +treemacs-git-mode
|
||||
;; If they aren't supported, fall back to simpler methods
|
||||
(when (and (memq +treemacs-git-mode '(deferred extended))
|
||||
(not (executable-find "python3")))
|
||||
(setq +treemacs-git-mode 'simple))
|
||||
(treemacs-git-mode +treemacs-git-mode)
|
||||
(setq treemacs-collapse-dirs
|
||||
(if (memq treemacs-git-mode '(extended deferred))
|
||||
3
|
||||
0))))
|
||||
|
||||
|
||||
(use-package! treemacs-evil
|
||||
@@ -43,3 +66,9 @@
|
||||
(use-package! treemacs-magit
|
||||
:when (featurep! :tools magit)
|
||||
:after treemacs magit)
|
||||
|
||||
|
||||
(use-package! treemacs-persp
|
||||
:when (featurep! :ui workspaces)
|
||||
:after treemacs
|
||||
:config (treemacs-set-scope-type 'Perspectives))
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; ui/treemacs/packages.el
|
||||
|
||||
(package! treemacs)
|
||||
(package! treemacs :pin "327bf63e58348e0b5070054477db801d5392cd75")
|
||||
;; These packages have no :pin because they're in the same repo
|
||||
(when (featurep! :editor evil +everywhere)
|
||||
(package! treemacs-evil))
|
||||
(package! treemacs-projectile)
|
||||
(when (featurep! :tools magit)
|
||||
(package! treemacs-magit))
|
||||
(when (featurep! :ui workspaces)
|
||||
(package! treemacs-persp))
|
||||
|
||||
@@ -1,10 +1,92 @@
|
||||
#+TITLE: :ui unicode
|
||||
#+TITLE: ui/unicode
|
||||
#+DATE: June 8, 2020
|
||||
#+SINCE: v2.0
|
||||
#+STARTUP: inlineimages nofold
|
||||
|
||||
This unicode extends Doom's ability to display non-English unicode.
|
||||
|
||||
This is for non-English Emacs users, for whom Doom's built-in unicode support in insufficient.
|
||||
* Table of Contents :TOC_3:noexport:
|
||||
- [[#description][Description]]
|
||||
- [[#maintainers][Maintainers]]
|
||||
- [[#module-flags][Module Flags]]
|
||||
- [[#plugins][Plugins]]
|
||||
- [[#prerequisites][Prerequisites]]
|
||||
- [[#features][Features]]
|
||||
- [[#configuration][Configuration]]
|
||||
- [[#getting-fonts-with-good-coverage][Getting fonts with good coverage]]
|
||||
- [[#advanced-configuration][Advanced configuration]]
|
||||
- [[#troubleshooting][Troubleshooting]]
|
||||
- [[#emacs-daemon-mode][Emacs daemon mode]]
|
||||
|
||||
* Description
|
||||
This module extends Doom's ability to display non-English unicode.
|
||||
It is primarily useful for non-English Emacs users, for whom Doom's built-in unicode support in insufficient.
|
||||
|
||||
This module relies on the [[https://github.com/rolandwalker/unicode-fonts][unicode-fonts]] package. It tries to setup the default emacs fontset to cover as many unicode glyphs as possible by scanning all available glyphs from all available fonts.
|
||||
|
||||
When this module is enabled...
|
||||
|
||||
+ Emacs will prefer to use the ~doom-unicode-font~ font to display non-latin glyphs if it provides coverage for them.
|
||||
+ The first time you run Emacs a unicode cache will be generated -- this will take a while!
|
||||
+ Doom will ignore the ~doom-unicode-font~ variable and the ~:unicode-font~ setting.
|
||||
+ The cache will be regenerated every time Emacs is made aware of new fonts or you change the font configuration e.g. by modifying ~doom-unicode-font~.
|
||||
+ The cache will be stored and should not be regenerated unless font-related configuration or the versions of relevant packages changes.
|
||||
|
||||
|
||||
** Maintainers
|
||||
This module has no dedicated maintainers.
|
||||
|
||||
** Module Flags
|
||||
This module provides no flags.
|
||||
|
||||
** Plugins
|
||||
+ [[https://github.com/rolandwalker/unicode-fonts][unicode-fonts]]
|
||||
|
||||
* Prerequisites
|
||||
This module has no prerequisites.
|
||||
|
||||
* Features
|
||||
# An in-depth list of features, how to use them, and their dependencies.
|
||||
|
||||
* Configuration
|
||||
The first font that will be analyzed to see if it contains the glyphs of non-latin characters will be ~doom-unicode-font~. To set this font place
|
||||
#+BEGIN_SRC elisp
|
||||
(setq doom-unicode-font (font-spec :family "Fira Mono"))
|
||||
#+END_SRC
|
||||
in your private =config.el= file. If your ~doom-font~ provides good unicode coverage you just set
|
||||
#+BEGIN_SRC elisp
|
||||
(setq doom-unicode-font doom-font)
|
||||
#+END_SRC
|
||||
If your font does not provide some glyphs, this package will try its best to find another font that does.
|
||||
|
||||
** Getting fonts with good coverage
|
||||
A list of fonts with good unicode coverage can be found on the page of the [[https://github.com/rolandwalker/unicode-fonts#minimum-useful-fonts][unicode-fonts]] package.
|
||||
|
||||
** Advanced configuration
|
||||
Consult the [[https://github.com/rolandwalker/unicode-font][unicode-fonts]] package documentation for a description of more advanced configuration. The configuration should be placed, as usual, in your private =config.el= wrapped in an ~(after! unicode-fonts)~ block. The variable ~unicode-fonts-blocks~ contains a list of all unicode block names and their character ranges. The default fonts to search for glyphs are in the variable ~unicode-fonts-block-font-mapping~.
|
||||
|
||||
If you want to use the font =Symbola= for =Miscellaneous Symbols= by default you could add
|
||||
#+BEGIN_SRC elisp
|
||||
(after! unicode-fonts
|
||||
(push "Symbola" (cadr (assoc "Miscellaneous Symbols" unicode-fonts-block-font-mapping))))
|
||||
#+END_SRC
|
||||
to your =config.el=.
|
||||
|
||||
If you want to redefine several blocks an efficient way would be
|
||||
#+BEGIN_SRC elisp
|
||||
(after! unicode-fonts
|
||||
(dolist (unicode-block '("Mathematical Alphanumeric Symbols"
|
||||
"Mathematical Operators"
|
||||
"Miscellaneous Mathematical Symbols-A"
|
||||
"Miscellaneous Mathematical Symbols-B"
|
||||
"Miscellaneous Symbols"
|
||||
"Miscellaneous Symbols and Arrows"
|
||||
"Miscellaneous Symbols and Pictographs"))
|
||||
(push "DejaVu Math TeX Gyre" (cadr (assoc unicode-block unicode-fonts-block-font-mapping)))))
|
||||
#+END_SRC
|
||||
|
||||
You can find a list of fonts available to emacs using ~M-x counsel-fonts~.
|
||||
|
||||
|
||||
* Troubleshooting
|
||||
# Common issues and their solution, or places to look for help.
|
||||
** TODO Emacs daemon mode
|
||||
Currently this module may fail setup fonts when emacs is run in daemon mode. See [[https://github.com/hlissner/doom-emacs/issues/3328][Bug 3328]].
|
||||
|
||||
@@ -7,15 +7,21 @@
|
||||
necessary."
|
||||
(setq-default bidi-display-reordering t
|
||||
doom-unicode-font nil)
|
||||
(if initial-window-system
|
||||
(if (display-graphic-p)
|
||||
(+unicode-setup-fonts-h (selected-frame))
|
||||
(add-hook 'after-make-frame-functions #'+unicode-setup-fonts-h))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +unicode-setup-fonts-h (&optional frame)
|
||||
"Initialize `unicode-fonts', if in a GUI session."
|
||||
"Initialize `unicode-fonts', if in a GUI session.
|
||||
|
||||
If doom-unicode-font is set, add it as preferred font for all unicode blocks."
|
||||
(when (and frame (display-graphic-p frame))
|
||||
(with-selected-frame frame
|
||||
(require 'unicode-fonts)
|
||||
(when doom-unicode-font
|
||||
(let ((doom-unicode-font-family (plist-get (font-face-attributes doom-unicode-font) :family)))
|
||||
(dolist (unicode-block unicode-fonts-block-font-mapping)
|
||||
(push doom-unicode-font-family (cadr unicode-block)))))
|
||||
;; NOTE will impact startup time on first run
|
||||
(unicode-fonts-setup))))
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; ui/unicode/packages.el
|
||||
|
||||
(package! unicode-fonts)
|
||||
(package! unicode-fonts :pin "7b88ae84e589f6c8b9386b2fb5a02ff4ccb91169")
|
||||
|
||||
@@ -23,5 +23,12 @@
|
||||
("m" git-gutter:mark-hunk)
|
||||
("p" git-gutter:popup-hunk)
|
||||
("R" git-gutter:set-start-revision)
|
||||
("q" nil :color blue)
|
||||
("Q" (git-gutter-mode -1) :color blue))
|
||||
("q"
|
||||
(when (get-buffer git-gutter:popup-buffer)
|
||||
(kill-buffer (get-buffer git-gutter:popup-buffer)))
|
||||
:color blue)
|
||||
("Q"
|
||||
(progn (git-gutter-mode -1)
|
||||
(when (get-buffer git-gutter:popup-buffer)
|
||||
(kill-buffer (get-buffer git-gutter:popup-buffer))))
|
||||
:color blue))
|
||||
|
||||
@@ -11,13 +11,13 @@
|
||||
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.")
|
||||
|
||||
|
||||
;;
|
||||
;; Packages
|
||||
;;; Packages
|
||||
|
||||
(use-package! git-gutter
|
||||
:commands git-gutter:revert-hunk git-gutter:stage-hunk
|
||||
@@ -28,42 +28,43 @@ 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))
|
||||
(setq-local git-gutter:init-function #'git-gutter-fr:init
|
||||
git-gutter:view-diff-function #'git-gutter-fr:view-diff-infos
|
||||
git-gutter:clear-function #'git-gutter-fr:clear
|
||||
git-gutter:window-width -1)
|
||||
(setq-local git-gutter:init-function 'nil
|
||||
git-gutter:view-diff-function #'git-gutter:view-diff-infos
|
||||
git-gutter:clear-function #'git-gutter:clear-diff-infos
|
||||
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
|
||||
;; <https://github.com/syohex/emacs-git-gutter/issues/24>. Apparently, the
|
||||
;; mode-enabling function for global minor modes gets called for new buffers
|
||||
;; while they are still in `fundamental-mode', before a major mode has been
|
||||
;; assigned. I don't know why this is the case, but adding `fundamental-mode'
|
||||
;; here fixes the issue.
|
||||
;; Disable in Org mode, as per syl20bnr/spacemacs#10555 and
|
||||
;; syohex/emacs-git-gutter#24. Apparently, the mode-enabling function for
|
||||
;; global minor modes gets called for new buffers while they are still in
|
||||
;; `fundamental-mode', before a major mode has been 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)
|
||||
|
||||
;; Only enable the backends that are available, so it doesn't have to check
|
||||
;; when opening each buffer.
|
||||
(setq git-gutter:handled-backends
|
||||
(cons 'git (cl-remove-if-not #'executable-find (list 'hg 'svn 'bzr)
|
||||
:key #'symbol-name)))
|
||||
|
||||
;; Update git-gutter on focus (in case I was using git externally)
|
||||
(add-hook 'focus-in-hook #'git-gutter:update-all-windows)
|
||||
|
||||
@@ -73,7 +74,8 @@ is deferred until the file is saved. Respects `git-gutter:disabled-modes'."
|
||||
`doom-escape-hook' hooks."
|
||||
(when (and git-gutter-mode
|
||||
(not (memq this-command '(git-gutter:stage-hunk
|
||||
git-gutter:revert-hunk))))
|
||||
git-gutter:revert-hunk)))
|
||||
(not inhibit-redisplay))
|
||||
(ignore (git-gutter)))))
|
||||
;; update git-gutter when using magit commands
|
||||
(advice-add #'magit-stage-file :after #'+vc-gutter-update-h)
|
||||
@@ -92,8 +94,11 @@ is deferred until the file is saved. Respects `git-gutter:disabled-modes'."
|
||||
|
||||
|
||||
;; subtle diff indicators in the fringe
|
||||
(when +vc-gutter-default-style
|
||||
(after! git-gutter-fringe
|
||||
(after! git-gutter-fringe
|
||||
(when +vc-gutter-default-style
|
||||
;; standardize default fringe width
|
||||
(if (fboundp 'fringe-mode) (fringe-mode '4))
|
||||
|
||||
;; places the git gutter outside the margins.
|
||||
(setq-default fringes-outside-margins t)
|
||||
;; thin fringe bitmaps
|
||||
@@ -102,10 +107,12 @@ 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
|
||||
(when +vc-gutter-default-style
|
||||
;; 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)))
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; ui/vc-gutter/packages.el
|
||||
|
||||
(package! git-gutter-fringe)
|
||||
(package! git-gutter-fringe :pin "da19a474137876b29b5658ee7e9ae366f2b65c1d")
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; ui/vi-tilde-fringe/packages.el
|
||||
|
||||
(package! vi-tilde-fringe)
|
||||
(package! vi-tilde-fringe :pin "f1597a8d54535bb1d84b442577b2024e6f910308")
|
||||
|
||||
@@ -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))
|
||||
|
||||
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
;;; ui/window-select/packages.el
|
||||
|
||||
(if (featurep! +switch-window)
|
||||
(package! switch-window)
|
||||
(package! ace-window))
|
||||
(package! switch-window :pin "8710f6304d843365fb59b6efe7e1f729d14e557c")
|
||||
(package! ace-window :pin "7003c88cd9cad58dc35c7cd13ebc61c355fb5be7"))
|
||||
|
||||
(when (featurep! +numbers)
|
||||
(package! winum))
|
||||
(package! winum :pin "c5455e866e8a5f7eab6a7263e2057aff5f1118b9"))
|
||||
|
||||
@@ -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 ()
|
||||
@@ -335,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 ()
|
||||
@@ -396,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
|
||||
@@ -492,32 +525,46 @@ the user to open a file in the new project.
|
||||
This be hooked to `projectile-after-switch-project-hook'."
|
||||
(when dir
|
||||
(setq +workspaces--project-dir dir))
|
||||
(when (and persp-mode +workspaces--project-dir)
|
||||
(unwind-protect
|
||||
(if (and (not (null +workspaces-on-switch-project-behavior))
|
||||
(or (eq +workspaces-on-switch-project-behavior t)
|
||||
(+workspace-buffer-list)))
|
||||
(let* ((persp
|
||||
(let ((project-name (doom-project-name +workspaces--project-dir)))
|
||||
(or (+workspace-get project-name t)
|
||||
(+workspace-new project-name))))
|
||||
(new-name (persp-name persp)))
|
||||
(+workspace-switch new-name)
|
||||
(with-current-buffer (doom-fallback-buffer)
|
||||
(setq default-directory +workspaces--project-dir))
|
||||
(unless current-prefix-arg
|
||||
(funcall +workspaces-switch-project-function +workspaces--project-dir))
|
||||
(+workspace-message
|
||||
(format "Switched to '%s' in new workspace" new-name)
|
||||
'success))
|
||||
(with-current-buffer (doom-fallback-buffer)
|
||||
(setq default-directory +workspaces--project-dir)
|
||||
(message "Switched to '%s'" (doom-project-name +workspaces--project-dir)))
|
||||
(with-demoted-errors "Workspace error: %s"
|
||||
(+workspace-rename (+workspace-current-name) (doom-project-name +workspaces--project-dir)))
|
||||
(unless current-prefix-arg
|
||||
(funcall +workspaces-switch-project-function +workspaces--project-dir)))
|
||||
(setq +workspaces--project-dir nil))))
|
||||
;; HACK Clear projectile-project-root, otherwise cached roots may interfere
|
||||
;; with project switch (see #3166)
|
||||
(let (projectile-project-root)
|
||||
(when (and persp-mode +workspaces--project-dir)
|
||||
(when projectile-before-switch-project-hook
|
||||
(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)))
|
||||
(or (+workspace-get project-name t)
|
||||
(+workspace-new project-name))))
|
||||
(new-name (persp-name persp)))
|
||||
(+workspace-switch new-name)
|
||||
(with-current-buffer (doom-fallback-buffer)
|
||||
(setq default-directory +workspaces--project-dir)
|
||||
(hack-dir-local-variables-non-file-buffer))
|
||||
(unless current-prefix-arg
|
||||
(funcall +workspaces-switch-project-function +workspaces--project-dir))
|
||||
(+workspace-message
|
||||
(format "Switched to '%s' in new workspace" new-name)
|
||||
'success))
|
||||
(with-current-buffer (doom-fallback-buffer)
|
||||
(setq default-directory +workspaces--project-dir)
|
||||
(hack-dir-local-variables-non-file-buffer)
|
||||
(message "Switched to '%s'" (doom-project-name +workspaces--project-dir)))
|
||||
(with-demoted-errors "Workspace error: %s"
|
||||
(+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)))))
|
||||
|
||||
|
||||
;;
|
||||
|
||||
@@ -50,11 +50,13 @@ stored in `persp-save-dir'.")
|
||||
(persp-mode +1)))))
|
||||
:config
|
||||
(setq persp-autokill-buffer-on-remove 'kill-weak
|
||||
persp-reset-windows-on-nil-window-conf nil
|
||||
persp-nil-hidden t
|
||||
persp-auto-save-fname "autosave"
|
||||
persp-save-dir (concat doom-etc-dir "workspaces/")
|
||||
persp-set-last-persp-for-new-frames t
|
||||
persp-switch-to-added-buffer nil
|
||||
persp-kill-foreign-buffer-behaviour 'kill
|
||||
persp-remove-buffers-from-nil-persp-behaviour nil
|
||||
persp-auto-resume-time -1 ; Don't auto-load on startup
|
||||
persp-auto-save-opt (if noninteractive 0 1)) ; auto-save on kill
|
||||
@@ -62,28 +64,36 @@ 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, so we get rid of it...
|
||||
(when (equal (car persp-names-cache) persp-nil-name)
|
||||
(pop persp-names-cache))
|
||||
;; ...and create a *real* main workspace to fill this role.
|
||||
(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 +118,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)
|
||||
@@ -171,7 +181,10 @@ stored in `persp-save-dir'.")
|
||||
("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)
|
||||
(when (featurep! :completion helm)
|
||||
(after! helm-projectile
|
||||
(setcar helm-source-projectile-projects-actions
|
||||
'("Switch to Project" . +workspaces-switch-to-project-h))))
|
||||
|
||||
;; Fix #1973: visual selection surviving workspace changes
|
||||
(add-hook 'persp-before-deactivate-functions #'deactivate-mark)
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; ui/workspaces/packages.el
|
||||
|
||||
(package! persp-mode)
|
||||
|
||||
(package! persp-mode :pin "391a7dc248c9c04b7ad424c696bdff578e14dd2c")
|
||||
|
||||
Reference in New Issue
Block a user