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-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 ()
|
||||
"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
|
||||
|
@ -218,7 +206,6 @@ extension, try to guess one."
|
|||
(def-package! command-log-mode
|
||||
:commands (command-log-mode global-command-log-mode)
|
||||
:config
|
||||
(set! :popup "*command-log*" :size 40 :align 'right :noselect t)
|
||||
(setq command-log-mode-auto-show 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)
|
||||
(defvar doom-init-ui-hook nil
|
||||
"List of hooks to run when the theme and font is initialized (or reloaded with
|
||||
`doom//reload-theme').")
|
||||
"List of hooks to run when core-ui is initialized.")
|
||||
|
||||
(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
|
||||
|
@ -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
|
||||
|
||||
(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))
|
||||
(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 hiding the mode-line
|
||||
;;
|
||||
|
||||
;; A minor mode for toggling the mode-line
|
||||
(defvar-local doom--modeline-format nil
|
||||
"The modeline format to use when `doom-hide-modeline-mode' is active. Don't
|
||||
set this directly. Let-bind it instead.")
|
||||
|
||||
(defvar-local doom--old-modeline-format nil
|
||||
"The old modeline format, so `doom-hide-modeline-mode' can revert when it's
|
||||
disabled.")
|
||||
|
||||
(define-minor-mode doom-hide-modeline-mode
|
||||
"Minor mode to hide the mode-line in the current buffer."
|
||||
:init-value nil
|
||||
:global nil
|
||||
(if doom-hide-modeline-mode
|
||||
(setq doom--old-modeline-format mode-line-format
|
||||
mode-line-format doom--modeline-format)
|
||||
(setq mode-line-format doom--old-modeline-format
|
||||
doom--old-modeline-format nil))
|
||||
(if (not doom-hide-modeline-mode)
|
||||
(setq mode-line-format doom--old-modeline-format
|
||||
doom--old-modeline-format nil)
|
||||
(setq doom--old-modeline-format mode-line-format
|
||||
mode-line-format doom--modeline-format)
|
||||
(add-hook 'after-change-major-mode-hook #'doom|hide-modeline-mode-reset nil t))
|
||||
(force-mode-line-update))
|
||||
|
||||
;; Ensure major-mode or theme changes don't overwrite these variables
|
||||
(put 'doom--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-hook t)
|
||||
|
||||
(defun doom|hide-modeline-mode-reset ()
|
||||
"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
|
||||
(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
|
||||
;; daemon Emacs is hairy.
|
||||
;;
|
||||
;; + Running `doom|init-ui' 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.
|
||||
(defun doom|init-ui (&optional frame)
|
||||
"Set the theme and load the font, in that order."
|
||||
(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))
|
||||
(defmacro def-modeline-segment! (name &rest forms)
|
||||
"Defines a modeline segment and byte compiles it."
|
||||
(declare (indent defun) (doc-string 2))
|
||||
(let ((sym (intern (format "doom-modeline-segment--%s" name))))
|
||||
`(progn
|
||||
(defun ,sym () ,@forms)
|
||||
,(unless (bound-and-true-p byte-compile-current-file)
|
||||
`(let (byte-compile-warnings)
|
||||
(byte-compile #',sym))))))
|
||||
|
||||
(defun doom|reload-ui-in-daemon (frame)
|
||||
"Reload the theme (and font) in an daemon frame."
|
||||
(when (or (daemonp) (not (display-graphic-p)))
|
||||
(with-selected-frame frame
|
||||
(run-with-timer 0.1 nil #'doom|init-ui))))
|
||||
(defsubst doom--prepare-modeline-segments (segments)
|
||||
(cl-loop for seg in segments
|
||||
if (stringp seg)
|
||||
collect seg
|
||||
else
|
||||
collect (list (intern (format "doom-modeline-segment--%s" (symbol-name seg))))))
|
||||
|
||||
;; register UI init hooks
|
||||
(add-hook 'doom-post-init-hook #'doom|init-ui)
|
||||
(add-hook! 'after-make-frame-functions #'(doom|init-ui doom|reload-ui-in-daemon))
|
||||
(defmacro def-modeline! (name lhs &optional rhs)
|
||||
"Defines a modeline format and byte-compiles it. NAME is a symbol to identify
|
||||
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))))))
|
||||
|
||||
;;
|
||||
;; Bootstrap
|
||||
;;
|
||||
(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)))))
|
||||
|
||||
;; prompts the user for confirmation when deleting a non-empty frame
|
||||
(define-key global-map [remap delete-frame] #'doom/delete-frame)
|
||||
;; simple name in frame title
|
||||
(setq-default frame-title-format '("DOOM Emacs"))
|
||||
;; auto-enabled in Emacs 25+; I'll do it myself
|
||||
(global-eldoc-mode -1)
|
||||
;; a good indicator that Emacs isn't frozen
|
||||
(add-hook 'doom-post-init-hook #'blink-cursor-mode)
|
||||
;; 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))
|
||||
(defun doom-set-modeline (key &optional default)
|
||||
"Set the modeline format. Does nothing if the modeline KEY doesn't exist. If
|
||||
DEFAULT is non-nil, set the default mode-line for all buffers."
|
||||
(when-let* ((modeline (doom-modeline key)))
|
||||
(setf (if default
|
||||
(default-value 'mode-line-format)
|
||||
(buffer-local-value 'mode-line-format (current-buffer)))
|
||||
modeline)))
|
||||
|
||||
|
||||
;;
|
||||
|
@ -331,6 +276,38 @@ instead)."
|
|||
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
|
||||
;;
|
||||
|
@ -366,8 +343,6 @@ See `doom-line-numbers-style' to control the style of line numbers to display."
|
|||
"Disable the display of line numbers."
|
||||
(doom|enable-line-numbers -1))
|
||||
|
||||
(add-hook! (prog-mode text-mode conf-mode) #'doom|enable-line-numbers)
|
||||
|
||||
;; Emacs 26+ has native line number support.
|
||||
;; Line number column. A faster (or equivalent, in the worst case) line number
|
||||
;; 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)
|
||||
"Defines a modeline segment and byte compiles it."
|
||||
(declare (indent defun) (doc-string 2))
|
||||
(let ((sym (intern (format "doom-modeline-segment--%s" name))))
|
||||
`(progn
|
||||
(defun ,sym () ,@forms)
|
||||
,(unless (bound-and-true-p byte-compile-current-file)
|
||||
`(let (byte-compile-warnings)
|
||||
(byte-compile #',sym))))))
|
||||
(defun doom|init-theme (&optional frame)
|
||||
"Set the theme and load the font, in that order."
|
||||
(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)))))
|
||||
|
||||
(defsubst doom--prepare-modeline-segments (segments)
|
||||
(cl-loop for seg in segments
|
||||
if (stringp seg)
|
||||
collect seg
|
||||
else
|
||||
collect (list (intern (format "doom-modeline-segment--%s" (symbol-name seg))))))
|
||||
(run-hooks 'doom-init-theme-hook))
|
||||
|
||||
(defmacro def-modeline! (name lhs &optional rhs)
|
||||
"Defines a modeline format and byte-compiles it. NAME is a symbol to identify
|
||||
it (used by `doom-modeline' for retrieval). LHS and RHS are lists of symbols of
|
||||
modeline segments defined with `def-modeline-segment!'.
|
||||
;; Getting themes to remain consistent across GUI Emacs, terminal Emacs and
|
||||
;; daemon Emacs is hairy.
|
||||
;;
|
||||
;; + 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:
|
||||
(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|reload-ui-in-daemon (frame)
|
||||
"Reload the theme (and font) in an daemon frame."
|
||||
(when (or (daemonp) (not (display-graphic-p)))
|
||||
(with-selected-frame frame
|
||||
(run-with-timer 0.1 nil #'doom|init-ui))))
|
||||
(add-hook! 'after-make-frame-functions #'(doom|init-theme doom|reload-ui-in-daemon))
|
||||
|
||||
(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
|
||||
DEFAULT is non-nil, set the default mode-line for all buffers."
|
||||
(when-let* ((modeline (doom-modeline key)))
|
||||
(setf (if default
|
||||
(default-value 'mode-line-format)
|
||||
(buffer-local-value 'mode-line-format (current-buffer)))
|
||||
modeline)))
|
||||
;;
|
||||
;; Bootstrap
|
||||
;;
|
||||
|
||||
;; auto-enabled in Emacs 25+; I'll do it myself
|
||||
(global-eldoc-mode -1)
|
||||
;; simple name in frame title
|
||||
(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)
|
||||
;;; core-ui.el ends here
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue