Major rewrite of core-ui
Phases out dependence on the doom-kill-buffer workflow, which ensured the user would always land on a real buffer (or the fallback buffer) after killing a buffer. This required all quit-window, kill-this-buffer and various buffer-killing commands be advised or remapped. There was no need, kill-buffer-query-functions is better. Also introduces a new hook: doom-init-theme-hook. doom-init-ui-hook still exists, but is used for UI initialization (surprise), while theme hooks should be moved over.
This commit is contained in:
parent
8e875bfa0e
commit
69385fac1a
2 changed files with 237 additions and 200 deletions
|
@ -52,18 +52,6 @@ modes are active and the buffer is read-only.")
|
||||||
ediff-split-window-function #'split-window-horizontally
|
ediff-split-window-function #'split-window-horizontally
|
||||||
ediff-window-setup-function #'ediff-setup-windows-plain)
|
ediff-window-setup-function #'ediff-setup-windows-plain)
|
||||||
|
|
||||||
(defun doom|dont-kill-scratch-buffer ()
|
|
||||||
"Don't kill the scratch buffer."
|
|
||||||
(or (not (string= (buffer-name) "*scratch*"))
|
|
||||||
(ignore (bury-buffer))))
|
|
||||||
(add-hook 'kill-buffer-query-functions #'doom|dont-kill-scratch-buffer)
|
|
||||||
|
|
||||||
;; temporary windows often have q bound to `quit-window', which only buries the
|
|
||||||
;; contained buffer. I rarely don't want that buffer killed, so...
|
|
||||||
(defun doom*quit-window (orig-fn &optional kill window)
|
|
||||||
(funcall orig-fn (not kill) window))
|
|
||||||
(advice-add #'quit-window :around #'doom*quit-window)
|
|
||||||
|
|
||||||
(defun doom|check-large-file ()
|
(defun doom|check-large-file ()
|
||||||
"Check if the buffer's file is large (see `doom-large-file-size'). If so, ask
|
"Check if the buffer's file is large (see `doom-large-file-size'). If so, ask
|
||||||
for confirmation to open it literally (read-only, disabled undo and in
|
for confirmation to open it literally (read-only, disabled undo and in
|
||||||
|
@ -218,7 +206,6 @@ extension, try to guess one."
|
||||||
(def-package! command-log-mode
|
(def-package! command-log-mode
|
||||||
:commands (command-log-mode global-command-log-mode)
|
:commands (command-log-mode global-command-log-mode)
|
||||||
:config
|
:config
|
||||||
(set! :popup "*command-log*" :size 40 :align 'right :noselect t)
|
|
||||||
(setq command-log-mode-auto-show t
|
(setq command-log-mode-auto-show t
|
||||||
command-log-mode-open-log-turns-on-mode t))
|
command-log-mode-open-log-turns-on-mode t))
|
||||||
|
|
||||||
|
|
424
core/core-ui.el
424
core/core-ui.el
|
@ -30,8 +30,11 @@ shorter major mode name in the mode-line. See `doom|set-mode-name'.")
|
||||||
|
|
||||||
;; Hook(s)
|
;; Hook(s)
|
||||||
(defvar doom-init-ui-hook nil
|
(defvar doom-init-ui-hook nil
|
||||||
"List of hooks to run when the theme and font is initialized (or reloaded with
|
"List of hooks to run when core-ui is initialized.")
|
||||||
`doom//reload-theme').")
|
|
||||||
|
(defvar doom-init-theme-hook nil
|
||||||
|
"List of hooks to run when the theme (and font) is initialized (or reloaded
|
||||||
|
with `doom//reload-theme').")
|
||||||
|
|
||||||
|
|
||||||
(setq-default
|
(setq-default
|
||||||
|
@ -72,45 +75,36 @@ shorter major mode name in the mode-line. See `doom|set-mode-name'.")
|
||||||
|
|
||||||
(fset #'yes-or-no-p #'y-or-n-p) ; y/n instead of yes/no
|
(fset #'yes-or-no-p #'y-or-n-p) ; y/n instead of yes/no
|
||||||
|
|
||||||
(defun doom-quit-p (&optional prompt)
|
|
||||||
"Return t if this session should be killed. Prompts the user for
|
|
||||||
confirmation."
|
|
||||||
(if (ignore-errors (doom-real-buffer-list))
|
|
||||||
(or (yes-or-no-p (format "››› %s" (or prompt "Quit Emacs?")))
|
|
||||||
(ignore (message "Aborted")))
|
|
||||||
t))
|
|
||||||
(setq confirm-kill-emacs nil)
|
|
||||||
(add-hook 'kill-emacs-query-functions #'doom-quit-p)
|
|
||||||
|
|
||||||
;; show typed keystrokes in minibuffer
|
;;
|
||||||
(defun doom|enable-ui-keystrokes () (setq echo-keystrokes 0.02))
|
;; A minor mode for hiding the mode-line
|
||||||
(defun doom|disable-ui-keystrokes () (setq echo-keystrokes 0))
|
;;
|
||||||
(doom|enable-ui-keystrokes)
|
|
||||||
;; ...but hide them while isearch is active
|
|
||||||
(add-hook 'isearch-mode-hook #'doom|disable-ui-keystrokes)
|
|
||||||
(add-hook 'isearch-mode-end-hook #'doom|enable-ui-keystrokes)
|
|
||||||
|
|
||||||
;; A minor mode for toggling the mode-line
|
|
||||||
(defvar-local doom--modeline-format nil
|
(defvar-local doom--modeline-format nil
|
||||||
"The modeline format to use when `doom-hide-modeline-mode' is active. Don't
|
"The modeline format to use when `doom-hide-modeline-mode' is active. Don't
|
||||||
set this directly. Let-bind it instead.")
|
set this directly. Let-bind it instead.")
|
||||||
|
|
||||||
(defvar-local doom--old-modeline-format nil
|
(defvar-local doom--old-modeline-format nil
|
||||||
"The old modeline format, so `doom-hide-modeline-mode' can revert when it's
|
"The old modeline format, so `doom-hide-modeline-mode' can revert when it's
|
||||||
disabled.")
|
disabled.")
|
||||||
|
|
||||||
(define-minor-mode doom-hide-modeline-mode
|
(define-minor-mode doom-hide-modeline-mode
|
||||||
"Minor mode to hide the mode-line in the current buffer."
|
"Minor mode to hide the mode-line in the current buffer."
|
||||||
:init-value nil
|
:init-value nil
|
||||||
:global nil
|
:global nil
|
||||||
(if doom-hide-modeline-mode
|
(if (not doom-hide-modeline-mode)
|
||||||
(setq doom--old-modeline-format mode-line-format
|
(setq mode-line-format doom--old-modeline-format
|
||||||
mode-line-format doom--modeline-format)
|
doom--old-modeline-format nil)
|
||||||
(setq mode-line-format doom--old-modeline-format
|
(setq doom--old-modeline-format mode-line-format
|
||||||
doom--old-modeline-format nil))
|
mode-line-format doom--modeline-format)
|
||||||
|
(add-hook 'after-change-major-mode-hook #'doom|hide-modeline-mode-reset nil t))
|
||||||
(force-mode-line-update))
|
(force-mode-line-update))
|
||||||
|
|
||||||
;; Ensure major-mode or theme changes don't overwrite these variables
|
;; Ensure major-mode or theme changes don't overwrite these variables
|
||||||
(put 'doom--modeline-format 'permanent-local t)
|
(put 'doom--modeline-format 'permanent-local t)
|
||||||
(put 'doom--old-modeline-format 'permanent-local t)
|
(put 'doom--old-modeline-format 'permanent-local t)
|
||||||
(put 'doom-hide-modeline-mode 'permanent-local t)
|
(put 'doom-hide-modeline-mode 'permanent-local t)
|
||||||
|
(put 'doom-hide-modeline-mode 'permanent-local-hook t)
|
||||||
|
|
||||||
(defun doom|hide-modeline-mode-reset ()
|
(defun doom|hide-modeline-mode-reset ()
|
||||||
"Sometimes, a major-mode is activated after `doom-hide-modeline-mode' is
|
"Sometimes, a major-mode is activated after `doom-hide-modeline-mode' is
|
||||||
|
@ -121,121 +115,72 @@ local value, whether or not it's permanent-local. Therefore, we cycle
|
||||||
(when doom-hide-modeline-mode
|
(when doom-hide-modeline-mode
|
||||||
(doom-hide-modeline-mode -1)
|
(doom-hide-modeline-mode -1)
|
||||||
(doom-hide-modeline-mode +1)))
|
(doom-hide-modeline-mode +1)))
|
||||||
(add-hook 'after-change-major-mode-hook #'doom|hide-modeline-mode-reset)
|
|
||||||
|
|
||||||
;; no modeline in completion popups
|
|
||||||
(add-hook 'completion-list-mode-hook #'doom-hide-modeline-mode)
|
|
||||||
|
|
||||||
;; undo/redo changes to Emacs' window layout
|
|
||||||
(defvar winner-dont-bind-my-keys t) ; I'll bind keys myself
|
|
||||||
(autoload 'winner-mode "winner" nil t)
|
|
||||||
(add-hook 'doom-init-ui-hook #'winner-mode)
|
|
||||||
|
|
||||||
;; highlight matching delimiters
|
|
||||||
(setq show-paren-delay 0.1
|
|
||||||
show-paren-highlight-openparen t
|
|
||||||
show-paren-when-point-inside-paren t)
|
|
||||||
(add-hook 'doom-init-ui-hook #'show-paren-mode)
|
|
||||||
|
|
||||||
;;; More reliable inter-window border
|
|
||||||
;; The native border "consumes" a pixel of the fringe on righter-most splits,
|
|
||||||
;; `window-divider' does not. Available since Emacs 25.1.
|
|
||||||
(setq-default window-divider-default-places t
|
|
||||||
window-divider-default-bottom-width 0
|
|
||||||
window-divider-default-right-width 1)
|
|
||||||
(add-hook 'doom-init-ui-hook #'window-divider-mode)
|
|
||||||
|
|
||||||
;; like diminish, but for major-modes. [pedantry intensifies]
|
|
||||||
(defun doom|set-mode-name ()
|
|
||||||
"Set the major mode's `mode-name', as dictated by `doom-major-mode-names'."
|
|
||||||
(when-let* ((name (cdr (assq major-mode doom-major-mode-names))))
|
|
||||||
(setq mode-name
|
|
||||||
(cond ((functionp name) (funcall name))
|
|
||||||
((stringp name) name)
|
|
||||||
(t (error "'%s' isn't a valid name for %s" name major-mode))))))
|
|
||||||
(add-hook 'after-change-major-mode-hook #'doom|set-mode-name)
|
|
||||||
|
|
||||||
|
|
||||||
;;
|
;;
|
||||||
;; Themes & fonts
|
;; Modeline library
|
||||||
;;
|
;;
|
||||||
|
|
||||||
;; Getting themes to remain consistent across GUI Emacs, terminal Emacs and
|
(defmacro def-modeline-segment! (name &rest forms)
|
||||||
;; daemon Emacs is hairy.
|
"Defines a modeline segment and byte compiles it."
|
||||||
;;
|
(declare (indent defun) (doc-string 2))
|
||||||
;; + Running `doom|init-ui' directly sorts out the initial GUI frame.
|
(let ((sym (intern (format "doom-modeline-segment--%s" name))))
|
||||||
;; + Attaching it to `after-make-frame-functions' sorts out daemon Emacs.
|
`(progn
|
||||||
;; + Waiting for 0.1s in `doom|reload-ui-in-daemon' fixes daemon Emacs started
|
(defun ,sym () ,@forms)
|
||||||
;; with `server-start' in an interactive session of Emacs AND in tty Emacs.
|
,(unless (bound-and-true-p byte-compile-current-file)
|
||||||
(defun doom|init-ui (&optional frame)
|
`(let (byte-compile-warnings)
|
||||||
"Set the theme and load the font, in that order."
|
(byte-compile #',sym))))))
|
||||||
(when doom-theme
|
|
||||||
(load-theme doom-theme t))
|
|
||||||
(condition-case-unless-debug ex
|
|
||||||
(when (display-graphic-p)
|
|
||||||
(when (fontp doom-font)
|
|
||||||
(set-frame-font doom-font nil (if frame (list frame) t))
|
|
||||||
(set-face-attribute 'fixed-pitch frame :font doom-font))
|
|
||||||
;; Fallback to `doom-unicode-font' for Unicode characters
|
|
||||||
(when (fontp doom-unicode-font)
|
|
||||||
(set-fontset-font t 'unicode doom-unicode-font frame))
|
|
||||||
;; ...and for variable-pitch-mode:
|
|
||||||
(when (fontp doom-variable-pitch-font)
|
|
||||||
(set-face-attribute 'variable-pitch frame :font doom-variable-pitch-font)))
|
|
||||||
('error
|
|
||||||
(if (string-prefix-p "Font not available: " (error-message-string ex))
|
|
||||||
(lwarn 'doom-ui :warning
|
|
||||||
"Could not find the '%s' font on your system, falling back to system font"
|
|
||||||
(font-get (caddr ex) :family))
|
|
||||||
(lwarn 'doom-ui :error
|
|
||||||
"Unexpected error while initializing fonts: %s"
|
|
||||||
(error-message-string ex)))))
|
|
||||||
(run-hooks 'doom-init-ui-hook))
|
|
||||||
|
|
||||||
(defun doom|reload-ui-in-daemon (frame)
|
(defsubst doom--prepare-modeline-segments (segments)
|
||||||
"Reload the theme (and font) in an daemon frame."
|
(cl-loop for seg in segments
|
||||||
(when (or (daemonp) (not (display-graphic-p)))
|
if (stringp seg)
|
||||||
(with-selected-frame frame
|
collect seg
|
||||||
(run-with-timer 0.1 nil #'doom|init-ui))))
|
else
|
||||||
|
collect (list (intern (format "doom-modeline-segment--%s" (symbol-name seg))))))
|
||||||
|
|
||||||
;; register UI init hooks
|
(defmacro def-modeline! (name lhs &optional rhs)
|
||||||
(add-hook 'doom-post-init-hook #'doom|init-ui)
|
"Defines a modeline format and byte-compiles it. NAME is a symbol to identify
|
||||||
(add-hook! 'after-make-frame-functions #'(doom|init-ui doom|reload-ui-in-daemon))
|
it (used by `doom-modeline' for retrieval). LHS and RHS are lists of symbols of
|
||||||
|
modeline segments defined with `def-modeline-segment!'.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
(def-modeline! minimal
|
||||||
|
(bar matches \" \" buffer-info)
|
||||||
|
(media-info major-mode))
|
||||||
|
(doom-set-modeline 'minimal t)"
|
||||||
|
(let ((sym (intern (format "doom-modeline-format--%s" name)))
|
||||||
|
(lhs-forms (doom--prepare-modeline-segments lhs))
|
||||||
|
(rhs-forms (doom--prepare-modeline-segments rhs)))
|
||||||
|
`(progn
|
||||||
|
(defun ,sym ()
|
||||||
|
(let ((lhs (list ,@lhs-forms))
|
||||||
|
(rhs (list ,@rhs-forms)))
|
||||||
|
(let ((rhs-str (format-mode-line rhs)))
|
||||||
|
(list lhs
|
||||||
|
(propertize
|
||||||
|
" " 'display
|
||||||
|
`((space :align-to (- (+ right right-fringe right-margin)
|
||||||
|
,(+ 1 (string-width rhs-str))))))
|
||||||
|
rhs-str))))
|
||||||
|
,(unless (bound-and-true-p byte-compile-current-file)
|
||||||
|
`(let (byte-compile-warnings)
|
||||||
|
(byte-compile #',sym))))))
|
||||||
|
|
||||||
;;
|
(defun doom-modeline (key)
|
||||||
;; Bootstrap
|
"Returns a mode-line configuration associated with KEY (a symbol). Throws an
|
||||||
;;
|
error if it doesn't exist."
|
||||||
|
(let ((fn (intern (format "doom-modeline-format--%s" key))))
|
||||||
|
(when (functionp fn)
|
||||||
|
`(:eval (,fn)))))
|
||||||
|
|
||||||
;; prompts the user for confirmation when deleting a non-empty frame
|
(defun doom-set-modeline (key &optional default)
|
||||||
(define-key global-map [remap delete-frame] #'doom/delete-frame)
|
"Set the modeline format. Does nothing if the modeline KEY doesn't exist. If
|
||||||
;; simple name in frame title
|
DEFAULT is non-nil, set the default mode-line for all buffers."
|
||||||
(setq-default frame-title-format '("DOOM Emacs"))
|
(when-let* ((modeline (doom-modeline key)))
|
||||||
;; auto-enabled in Emacs 25+; I'll do it myself
|
(setf (if default
|
||||||
(global-eldoc-mode -1)
|
(default-value 'mode-line-format)
|
||||||
;; a good indicator that Emacs isn't frozen
|
(buffer-local-value 'mode-line-format (current-buffer)))
|
||||||
(add-hook 'doom-post-init-hook #'blink-cursor-mode)
|
modeline)))
|
||||||
;; standardize default fringe width
|
|
||||||
(if (fboundp 'fringe-mode) (fringe-mode doom-fringe-size))
|
|
||||||
;; draw me like one of your French editors
|
|
||||||
(tooltip-mode -1) ; relegate tooltips to echo area only
|
|
||||||
(menu-bar-mode -1)
|
|
||||||
(if (fboundp 'tool-bar-mode) (tool-bar-mode -1))
|
|
||||||
(if (fboundp 'scroll-bar-mode) (scroll-bar-mode -1))
|
|
||||||
|
|
||||||
(defun doom|no-fringes-in-minibuffer ()
|
|
||||||
"Disable fringes in the minibuffer window."
|
|
||||||
(set-window-fringes (minibuffer-window) 0 0 nil))
|
|
||||||
(add-hook! '(doom-post-init-hook minibuffer-setup-hook)
|
|
||||||
#'doom|no-fringes-in-minibuffer)
|
|
||||||
|
|
||||||
(defun doom|protect-visible-buffers ()
|
|
||||||
"Don't kill the current buffer if it is visible in another window (bury it
|
|
||||||
instead)."
|
|
||||||
(not (delq (selected-window)
|
|
||||||
(get-buffer-window-list nil nil t))))
|
|
||||||
(add-hook! doom-post-init
|
|
||||||
(add-hook 'kill-buffer-query-functions #'doom|protect-visible-buffers))
|
|
||||||
|
|
||||||
|
|
||||||
;;
|
;;
|
||||||
|
@ -331,6 +276,38 @@ instead)."
|
||||||
fill-column)))
|
fill-column)))
|
||||||
|
|
||||||
|
|
||||||
|
;;
|
||||||
|
;; Built-in packages
|
||||||
|
;;
|
||||||
|
|
||||||
|
;; show typed keystrokes in minibuffer
|
||||||
|
(defun doom|enable-ui-keystrokes () (setq echo-keystrokes 0.02))
|
||||||
|
(defun doom|disable-ui-keystrokes () (setq echo-keystrokes 0))
|
||||||
|
(doom|enable-ui-keystrokes)
|
||||||
|
;; ...but hide them while isearch is active
|
||||||
|
(add-hook 'isearch-mode-hook #'doom|disable-ui-keystrokes)
|
||||||
|
(add-hook 'isearch-mode-end-hook #'doom|enable-ui-keystrokes)
|
||||||
|
|
||||||
|
;; undo/redo changes to Emacs' window layout
|
||||||
|
(defvar winner-dont-bind-my-keys t) ; I'll bind keys myself
|
||||||
|
(autoload 'winner-mode "winner" nil t)
|
||||||
|
(add-hook 'doom-init-ui-hook #'winner-mode)
|
||||||
|
|
||||||
|
;; highlight matching delimiters
|
||||||
|
(setq show-paren-delay 0.1
|
||||||
|
show-paren-highlight-openparen t
|
||||||
|
show-paren-when-point-inside-paren t)
|
||||||
|
(add-hook 'doom-init-ui-hook #'show-paren-mode)
|
||||||
|
|
||||||
|
;;; More reliable inter-window border
|
||||||
|
;; The native border "consumes" a pixel of the fringe on righter-most splits,
|
||||||
|
;; `window-divider' does not. Available since Emacs 25.1.
|
||||||
|
(setq-default window-divider-default-places t
|
||||||
|
window-divider-default-bottom-width 0
|
||||||
|
window-divider-default-right-width 1)
|
||||||
|
(add-hook 'doom-init-ui-hook #'window-divider-mode)
|
||||||
|
|
||||||
|
|
||||||
;;
|
;;
|
||||||
;; Line numbers
|
;; Line numbers
|
||||||
;;
|
;;
|
||||||
|
@ -366,8 +343,6 @@ See `doom-line-numbers-style' to control the style of line numbers to display."
|
||||||
"Disable the display of line numbers."
|
"Disable the display of line numbers."
|
||||||
(doom|enable-line-numbers -1))
|
(doom|enable-line-numbers -1))
|
||||||
|
|
||||||
(add-hook! (prog-mode text-mode conf-mode) #'doom|enable-line-numbers)
|
|
||||||
|
|
||||||
;; Emacs 26+ has native line number support.
|
;; Emacs 26+ has native line number support.
|
||||||
;; Line number column. A faster (or equivalent, in the worst case) line number
|
;; Line number column. A faster (or equivalent, in the worst case) line number
|
||||||
;; plugin than `linum-mode'.
|
;; plugin than `linum-mode'.
|
||||||
|
@ -442,69 +417,144 @@ character that looks like a space that `whitespace-mode' won't affect.")
|
||||||
|
|
||||||
|
|
||||||
;;
|
;;
|
||||||
;; Modeline
|
;; Theme & font
|
||||||
;;
|
;;
|
||||||
|
|
||||||
(defmacro def-modeline-segment! (name &rest forms)
|
(defun doom|init-theme (&optional frame)
|
||||||
"Defines a modeline segment and byte compiles it."
|
"Set the theme and load the font, in that order."
|
||||||
(declare (indent defun) (doc-string 2))
|
(when doom-theme
|
||||||
(let ((sym (intern (format "doom-modeline-segment--%s" name))))
|
(load-theme doom-theme t))
|
||||||
`(progn
|
(condition-case-unless-debug ex
|
||||||
(defun ,sym () ,@forms)
|
(when (display-graphic-p)
|
||||||
,(unless (bound-and-true-p byte-compile-current-file)
|
(when (fontp doom-font)
|
||||||
`(let (byte-compile-warnings)
|
(set-frame-font doom-font nil (if frame (list frame) t))
|
||||||
(byte-compile #',sym))))))
|
(set-face-attribute 'fixed-pitch frame :font doom-font))
|
||||||
|
;; Fallback to `doom-unicode-font' for Unicode characters
|
||||||
|
(when (fontp doom-unicode-font)
|
||||||
|
(set-fontset-font t 'unicode doom-unicode-font frame))
|
||||||
|
;; ...and for variable-pitch-mode:
|
||||||
|
(when (fontp doom-variable-pitch-font)
|
||||||
|
(set-face-attribute 'variable-pitch frame :font doom-variable-pitch-font)))
|
||||||
|
('error
|
||||||
|
(if (string-prefix-p "Font not available: " (error-message-string ex))
|
||||||
|
(lwarn 'doom-ui :warning
|
||||||
|
"Could not find the '%s' font on your system, falling back to system font"
|
||||||
|
(font-get (caddr ex) :family))
|
||||||
|
(lwarn 'doom-ui :error
|
||||||
|
"Unexpected error while initializing fonts: %s"
|
||||||
|
(error-message-string ex)))))
|
||||||
|
|
||||||
(defsubst doom--prepare-modeline-segments (segments)
|
(run-hooks 'doom-init-theme-hook))
|
||||||
(cl-loop for seg in segments
|
|
||||||
if (stringp seg)
|
|
||||||
collect seg
|
|
||||||
else
|
|
||||||
collect (list (intern (format "doom-modeline-segment--%s" (symbol-name seg))))))
|
|
||||||
|
|
||||||
(defmacro def-modeline! (name lhs &optional rhs)
|
;; Getting themes to remain consistent across GUI Emacs, terminal Emacs and
|
||||||
"Defines a modeline format and byte-compiles it. NAME is a symbol to identify
|
;; daemon Emacs is hairy.
|
||||||
it (used by `doom-modeline' for retrieval). LHS and RHS are lists of symbols of
|
;;
|
||||||
modeline segments defined with `def-modeline-segment!'.
|
;; + Running `doom|init-theme' directly sorts out the initial GUI frame.
|
||||||
|
;; + Attaching it to `after-make-frame-functions' sorts out daemon Emacs.
|
||||||
|
;; + Waiting for 0.1s in `doom|reload-ui-in-daemon' fixes daemon Emacs started
|
||||||
|
;; with `server-start' in an interactive session of Emacs AND in tty Emacs.
|
||||||
|
(add-hook 'doom-init-ui-hook #'doom|init-theme)
|
||||||
|
|
||||||
Example:
|
(defun doom|reload-ui-in-daemon (frame)
|
||||||
(def-modeline! minimal
|
"Reload the theme (and font) in an daemon frame."
|
||||||
(bar matches \" \" buffer-info)
|
(when (or (daemonp) (not (display-graphic-p)))
|
||||||
(media-info major-mode))
|
(with-selected-frame frame
|
||||||
(doom-set-modeline 'minimal t)"
|
(run-with-timer 0.1 nil #'doom|init-ui))))
|
||||||
(let ((sym (intern (format "doom-modeline-format--%s" name)))
|
(add-hook! 'after-make-frame-functions #'(doom|init-theme doom|reload-ui-in-daemon))
|
||||||
(lhs-forms (doom--prepare-modeline-segments lhs))
|
|
||||||
(rhs-forms (doom--prepare-modeline-segments rhs)))
|
|
||||||
`(progn
|
|
||||||
(defun ,sym ()
|
|
||||||
(let ((lhs (list ,@lhs-forms))
|
|
||||||
(rhs (list ,@rhs-forms)))
|
|
||||||
(let ((rhs-str (format-mode-line rhs)))
|
|
||||||
(list lhs
|
|
||||||
(propertize
|
|
||||||
" " 'display
|
|
||||||
`((space :align-to (- (+ right right-fringe right-margin)
|
|
||||||
,(+ 1 (string-width rhs-str))))))
|
|
||||||
rhs-str))))
|
|
||||||
,(unless (bound-and-true-p byte-compile-current-file)
|
|
||||||
`(let (byte-compile-warnings)
|
|
||||||
(byte-compile #',sym))))))
|
|
||||||
|
|
||||||
(defun doom-modeline (key)
|
|
||||||
"Returns a mode-line configuration associated with KEY (a symbol). Throws an
|
|
||||||
error if it doesn't exist."
|
|
||||||
(let ((fn (intern (format "doom-modeline-format--%s" key))))
|
|
||||||
(when (functionp fn)
|
|
||||||
`(:eval (,fn)))))
|
|
||||||
|
|
||||||
(defun doom-set-modeline (key &optional default)
|
;;
|
||||||
"Set the modeline format. Does nothing if the modeline KEY doesn't exist. If
|
;; Bootstrap
|
||||||
DEFAULT is non-nil, set the default mode-line for all buffers."
|
;;
|
||||||
(when-let* ((modeline (doom-modeline key)))
|
|
||||||
(setf (if default
|
;; auto-enabled in Emacs 25+; I'll do it myself
|
||||||
(default-value 'mode-line-format)
|
(global-eldoc-mode -1)
|
||||||
(buffer-local-value 'mode-line-format (current-buffer)))
|
;; simple name in frame title
|
||||||
modeline)))
|
(setq-default frame-title-format '("DOOM Emacs"))
|
||||||
|
;; draw me like one of your French editors
|
||||||
|
(tooltip-mode -1) ; relegate tooltips to echo area only
|
||||||
|
(menu-bar-mode -1)
|
||||||
|
(if (fboundp 'tool-bar-mode) (tool-bar-mode -1))
|
||||||
|
(if (fboundp 'scroll-bar-mode) (scroll-bar-mode -1))
|
||||||
|
;; standardize default fringe width
|
||||||
|
(if (fboundp 'fringe-mode) (fringe-mode doom-fringe-size))
|
||||||
|
;; prompts the user for confirmation when deleting a non-empty frame
|
||||||
|
(define-key global-map [remap delete-frame] #'doom/delete-frame)
|
||||||
|
|
||||||
|
;; a good indicator that Emacs isn't frozen
|
||||||
|
(add-hook 'doom-init-ui-hook #'blink-cursor-mode)
|
||||||
|
;; no modeline in completion popups
|
||||||
|
(add-hook 'completion-list-mode-hook #'doom-hide-modeline-mode)
|
||||||
|
;; line numbers in most modes
|
||||||
|
(add-hook! (prog-mode text-mode conf-mode) #'doom|enable-line-numbers)
|
||||||
|
|
||||||
|
|
||||||
|
;; Customized confirmation prompt for quitting Emacs
|
||||||
|
(defun doom-quit-p (&optional prompt)
|
||||||
|
"Return t if this session should be killed. Prompts the user for
|
||||||
|
confirmation."
|
||||||
|
(if (ignore-errors (doom-real-buffer-list))
|
||||||
|
(or (yes-or-no-p (format "››› %s" (or prompt "Quit Emacs?")))
|
||||||
|
(ignore (message "Aborted")))
|
||||||
|
t))
|
||||||
|
(setq confirm-kill-emacs #'doom-quit-p)
|
||||||
|
|
||||||
|
(defun doom|no-fringes-in-minibuffer ()
|
||||||
|
"Disable fringes in the minibuffer window."
|
||||||
|
(set-window-fringes (minibuffer-window) 0 0 nil))
|
||||||
|
(add-hook! '(doom-init-ui-hook minibuffer-setup-hook)
|
||||||
|
#'doom|no-fringes-in-minibuffer)
|
||||||
|
|
||||||
|
(defun doom|set-mode-name ()
|
||||||
|
"Set the major mode's `mode-name', as dictated by `doom-major-mode-names'."
|
||||||
|
(when-let* ((name (cdr (assq major-mode doom-major-mode-names))))
|
||||||
|
(setq mode-name
|
||||||
|
(cond ((functionp name) (funcall name))
|
||||||
|
((stringp name) name)
|
||||||
|
(t (error "'%s' isn't a valid name for %s" name major-mode))))))
|
||||||
|
|
||||||
|
(defun doom|protect-visible-buffers ()
|
||||||
|
"Don't kill the current buffer if it is visible in another window (bury it
|
||||||
|
instead)."
|
||||||
|
(not (delq (selected-window) (get-buffer-window-list nil nil t))))
|
||||||
|
|
||||||
|
(defun doom|protect-fallback-buffer ()
|
||||||
|
"Don't kill the scratch buffer."
|
||||||
|
(not (eq (current-buffer) (doom-fallback-buffer))))
|
||||||
|
|
||||||
|
(defun doom*switch-to-fallback-buffer-maybe (orig-fn)
|
||||||
|
"Advice for `kill-this-buffer'. If there are no real buffers left, switch to
|
||||||
|
`doom-fallback-buffer'."
|
||||||
|
(let ((buf (current-buffer)))
|
||||||
|
(cond ((window-at-side-p)
|
||||||
|
(quit-window))
|
||||||
|
((eq buf (doom-fallback-buffer))
|
||||||
|
(bury-buffer))
|
||||||
|
(t
|
||||||
|
(let ((real-p (doom-real-buffer-p buf)))
|
||||||
|
(funcall orig-fn)
|
||||||
|
(cond ((eq buf (current-buffer))
|
||||||
|
(doom--cycle-real-buffers nil))
|
||||||
|
((and real-p (not (doom-real-buffer-p)))
|
||||||
|
(doom--cycle-real-buffers -1))
|
||||||
|
(t
|
||||||
|
(message "Nowhere to go!"))))))))
|
||||||
|
|
||||||
|
|
||||||
|
(defun doom|init-ui ()
|
||||||
|
"Initialize Doom's user interface by applying all its advice and hooks."
|
||||||
|
;; Switch to `doom-fallback-buffer' if on last real buffer
|
||||||
|
(advice-add #'kill-this-buffer :around #'doom*switch-to-fallback-buffer-maybe)
|
||||||
|
;; Don't kill the fallback buffer
|
||||||
|
(add-hook 'kill-buffer-query-functions #'doom|protect-fallback-buffer)
|
||||||
|
;; Don't kill buffers that are visible else, only bury them
|
||||||
|
(add-hook 'kill-buffer-query-functions #'doom|protect-visible-buffers)
|
||||||
|
;; Renames major-modes [pedantry intensifies]
|
||||||
|
(add-hook 'after-change-major-mode-hook #'doom|set-mode-name)
|
||||||
|
;;
|
||||||
|
(run-hooks 'doom-init-ui-hook))
|
||||||
|
|
||||||
|
(add-hook 'doom-init-hook #'doom|init-ui)
|
||||||
|
|
||||||
(provide 'core-ui)
|
(provide 'core-ui)
|
||||||
;;; core-ui.el ends here
|
;;; core-ui.el ends here
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue