diff --git a/core/core-scratch.el b/core/core-scratch.el index addfd5bc0..780a52580 100644 --- a/core/core-scratch.el +++ b/core/core-scratch.el @@ -10,10 +10,11 @@ "The global and persistent scratch buffer for doom.") (defvar doom-buffer-name "*doom*" "The name of the doom scratch buffer.") +(defvar-local doom-buffer-edited nil + "If non-nil, the scratch buffer has been edited.") (define-derived-mode doom-mode text-mode "DOOM" - "Major mode for special DOOM buffers." - :group 'doom) + "Major mode for special DOOM buffers.") ;; Don't kill the scratch buffer (add-hook! 'kill-buffer-query-functions @@ -25,6 +26,11 @@ (doom-mode-init) (setq mode-line-format nil)) +(defun doom-mode-erase-on-insert () + (erase-buffer) + (setq doom-buffer-edited t) + (remove-hook 'evil-insert-state-entry-hook 'doom-mode-erase-on-insert t)) + (defun doom-mode-init (&optional auto-detect-frame) (unless (buffer-live-p doom-buffer) (setq doom-buffer nil)) (let ((old-scratch (get-buffer "*scratch*"))) @@ -36,18 +42,23 @@ (setq doom-buffer (get-buffer-create doom-buffer-name))) (with-current-buffer doom-buffer (doom-mode) + (add-hook 'evil-insert-state-entry-hook 'doom-mode-erase-on-insert nil t) + (add-hook 'after-change-major-mode-hook 'doom-mode-erase-on-insert nil t) (erase-buffer) + (setq doom-buffer-edited nil) (insert (let* ((auto-detect-frame (or auto-detect-frame (not (display-graphic-p)))) - (width (- (if auto-detect-frame (window-width) (cdr (assq 'width default-frame-alist))) 3)) - (lead (make-string (truncate (/ (- width 78) 2)) ? ))) + (width (if auto-detect-frame + (window-width) + (cdr (assq 'width default-frame-alist)))) + (height (if auto-detect-frame + (window-height) + (cdr (assq 'height default-frame-alist)))) + (lead (make-string (truncate (max 0 (/ (- width 78) 2))) ? ))) (concat (propertize (concat - (make-string (min 3 (/ (if auto-detect-frame - (window-height) - (cdr (assq 'height default-frame-alist))) 5)) - ?\n) + (make-string (min 3 (truncate (/ height 5))) ?\n) lead "================= =============== =============== ======== ========\n" lead "\\\\ . . . . . . .\\\\ //. . . . . . .\\\\ //. . . . . . .\\\\ \\\\. . .\\\\// . . //\n" lead "||. . ._____. . .|| ||. . ._____. . .|| ||. . ._____. . .|| || . . .\\/ . . .||\n" @@ -71,15 +82,15 @@ "\n\n" (propertize (s-trim-right - (s-center (1- width) "Press `,m` to open recent files, or `,E` to access emacs.d")) + (s-center (max 0 (1- width)) "Press `,m` to open recent files, or `,E` to access emacs.d")) 'face 'font-lock-keyword-face) (concat "\n\n" - (s-trim-right (s-center (- width 2) + (s-trim-right (s-center (max 0 (- width 2)) (format "Loaded in %.3fs" (float-time (time-subtract after-init-time emacs-start-time))))))))) (back-to-indentation) - (doom|update-scratch-buffer))) + (doom|update-scratch-buffer nil t))) (provide 'core-scratch) ;;; core-scratch.el ends here diff --git a/core/defuns/defuns-buffers.el b/core/defuns/defuns-buffers.el index aca65e9d2..8de8bf1a7 100644 --- a/core/defuns/defuns-buffers.el +++ b/core/defuns/defuns-buffers.el @@ -51,11 +51,12 @@ Inspired from http://demonastery.org/2013/04/emacs-evil-narrow-region/" (--filter (memq it assocbuf) (buffer-list)) (buffer-list))) project-root) - (aif (and project-p (doom/project-root t)) - (funcall (if (eq project-p 'not) '-remove '-filter) - (lambda (b) (projectile-project-buffer-p b it)) - buffers) - buffers))) + (append (aif (and project-p (doom/project-root t)) + (funcall (if (eq project-p 'not) '-remove '-filter) + (lambda (b) (projectile-project-buffer-p b it)) + buffers) + buffers) + (list doom-buffer)))) ;;;###autoload (defun doom/get-buffer-names (&optional project-p) @@ -96,24 +97,25 @@ Inspired from http://demonastery.org/2013/04/emacs-evil-narrow-region/" (-filter #'doom/real-buffer-p (or buffer-list (doom/get-buffers)))) ;;;###autoload -(defun doom/kill-real-buffer () +(defun doom/kill-real-buffer (&optional arg) "Kill buffer (but only bury scratch buffer), then switch to a real buffer. Only buries the buffer if it is being displayed in another window." - (interactive) - (let (new-dir) - (if (string-match-p doom-buffer-name (or (buffer-name) "")) + (interactive (list t)) + (if (eq doom-buffer (current-buffer)) (progn - (doom-mode-init t) - (message "Already in the scratch buffer")) - (setq new-dir (doom/project-root)) - (if (> (length (get-buffer-window-list (current-buffer) nil t)) 1) - (bury-buffer) - (kill-this-buffer)) - (if (doom/popup-p (selected-window)) - (doom/popup-close) - (unless (doom/real-buffer-p (current-buffer)) - (doom/previous-real-buffer) - (doom|update-scratch-buffer-cwd new-dir)))))) + (when (= (length (get-buffer-window-list doom-buffer nil t)) 1) + (doom-mode-init t)) + (when arg (message "Already in scratch buffer"))) + (let ((new-dir (doom/project-root))) + (if (doom/popup-p (selected-window)) + (doom/popup-close) + (if (> (length (get-buffer-window-list (current-buffer) nil t)) 1) + (bury-buffer) + (kill-this-buffer)) + (unless (doom/real-buffer-p (current-buffer)) + (doom/previous-real-buffer)) + (when (get-buffer-window-list doom-buffer nil t) + (doom|update-scratch-buffer new-dir)))))) ;;;###autoload (defun doom/kill-unreal-buffers () @@ -189,13 +191,18 @@ left, create a scratch buffer." (cl-incf i))))) ;;;###autoload -(defun doom/real-buffer-p (&optional buffer-or-name) - (let ((buffer (if buffer-or-name (get-buffer buffer-or-name) (current-buffer)))) - (when (buffer-live-p buffer) - (not (--any? (if (stringp it) - (string-match-p it (buffer-name buffer)) - (eq (buffer-local-value 'major-mode buffer) it)) - doom-unreal-buffers))))) +(defun doom/real-buffer-p (&optional buffer) + "Returns whether BUFFER a 'real' buffer or not. Real means it isn't a popup, +temporary, scratch or special buffer." + (setq buffer (get-buffer (or buffer (current-buffer)))) + (when (buffer-live-p buffer) + (with-current-buffer buffer + (not (or (apply #'derived-mode-p + (-filter 'symbolp doom-unreal-buffers)) + (--any? (if (stringp it) + (string-match-p it (buffer-name buffer)) + (eq major-mode it)) + doom-unreal-buffers)))))) ;; Inspired by spacemacs ;;;###autoload @@ -222,7 +229,7 @@ left, create a scratch buffer." (evil-define-command doom:kill-all-buffers (&optional bang) "Kill all project buffers. If BANG, kill *all* buffers (in workgroup)." (interactive "") - (doom--kill-buffers (doom/get-buffers (not bang))) + (doom--kill-buffers (--filter (eq it doom-buffer) (doom/get-buffers (not bang)))) (mapc (lambda (w) (when (eq (window-buffer w) doom-buffer) (delete-window w))) (doom/get-visible-windows)))