I am using (global-tab-bar-mode) in emacs, but almost all commands that have output (like shell commands) will split the current window and make another, ignoring tabs completely, which I do not want, I want everything to use tabs instead of opening new windows! My current tab config (mainly AI generated because my elisp is not good at all):
;; Tab management
(use-package tab-bar
:ensure nil
:init
(tab-bar-mode 1)
:config
(setq tab-bar-new-tab-choice "*scratch*"
tab-bar-close-button nil
tab-bar-new-button nil
tab-bar-format '(tab-bar-format-tabs tab-bar-separator))
;; Auto-close empty non-scratch tabs
(defun auto-close-empty-tab ()
"Close tab if it only contains an empty non-scratch buffer."
(when (and (eq (length (window-list)) 1)
(not (string-match-p "\\*scratch\\*" (buffer-name)))
(eq (buffer-size) 0))
(tab-bar-close-tab)))
(add-hook 'kill-buffer-hook 'auto-close-empty-tab)
;; Tab display function
(defun my/display-in-tab (buffer &optional _)
"Display BUFFER in a new tab reliably."
(let ((tab-bar-new-tab-choice t))
(tab-bar-new-tab)
(set-window-buffer (selected-window) buffer)
(selected-window)))
;; Set for all buffers
(setq display-buffer-base-action '((my/display-in-tab)))
(setq display-buffer-alist nil)
;; Window management overrides
(defun my/ignore-split (&rest _)
"Ignore split commands safely.")
(advice-add 'split-window :override #'my/ignore-split)
(advice-add 'split-window-right :override #'my/ignore-split)
(advice-add 'split-window-below :override #'my/ignore-split)
(defun my/safe-switch-to-buffer (buffer &optional norecord)
"Switch to BUFFER in new tab, handling special cases."
(cond
((minibufferp) (switch-to-buffer buffer norecord))
(t (my/display-in-tab buffer))))
(advice-add 'switch-to-buffer :override #'my/safe-switch-to-buffer)
(defun my/safe-delete-window (&optional window)
"Prevent deleting the sole window."
(unless (one-window-p)
(delete-window window)))
(advice-add 'delete-window :override #'my/safe-delete-window)
;; Tab protection
(defun protect-last-tab (&rest _)
"Prevent deleting the last remaining tab in a frame."
(when (<= (length (tab-bar-tabs)) 1)
(tab-bar-new-tab)))
(advice-add 'tab-bar-close-tab :before #'protect-last-tab)
(advice-add 'tab-close :before #'protect-last-tab))
;; Add this function to clone tabs
(defun clone-tab ()
"Clone current tab with its buffer."
(interactive)
(let* ((current-buf (current-buffer)))
(tab-bar-new-tab)
(switch-to-buffer current-buf)))
;; Modify the auto-close function to handle scratch buffers correctly
(defun auto-close-empty-tab ()
"Close tab if it only contains an empty non-scratch buffer."
(when (and (eq (length (window-list)) 1)
(not (string-match-p "\\*scratch\\*" (buffer-name)))
(eq (buffer-size) 0))
(tab-bar-close-tab)))
;; Update the display function to prevent automatic cloning
(defun my/display-in-tab (buffer &optional _)
"Display BUFFER in a new tab reliably."
(let ((tab-bar-new-tab-choice t))
(tab-bar-new-tab)
(set-window-buffer (selected-window) buffer)
(selected-window)))
;; Simplify the initial tab setup
(add-hook 'after-init-hook
(lambda ()
(tab-bar-close-other-tabs)
(switch-to-buffer "*scratch*")))
this attempts to hook onto splitting windows, but is completely broken and I cannot seem to find where, as it will duplicate the current tab and open a new scratch buffer tab when trying to run (tab-bar-new-tab), it will open multiple tabs on startup, and the new tabs do not correctly register content, so this solution does not really work. I am looking to do something similar, as it would be possible and reliable to add an advice to each individual command which would open a new window, but it would be a pain, and I feel like it would be possible to do something like this by hooking into split window functions. Can anyone help?
Edit for clarity: I am very new, but I want to do this not because I want the same thing I got from other editors, (I have worked tabless before), but because it is just a much nicer paradigm that I like, and while I intend to learn windows much more, I do want a primarily tab-based workflow, and it interrupts mine when the window splits unnecesarily.