EWM - Emacs Wayland Manager setup, dynamic tabs setup v1
This commit is contained in:
parent
dc38d0dec3
commit
c52e577181
196
init.el
196
init.el
|
|
@ -865,6 +865,202 @@
|
||||||
:config
|
:config
|
||||||
(setq prettier-js-use-modules-bin t))
|
(setq prettier-js-use-modules-bin t))
|
||||||
|
|
||||||
|
;; Emacs desktop environment
|
||||||
|
; Emacs Wayland Manager (EWM)
|
||||||
|
(when (and (executable-find "ewm-launch") (string= (getenv "XDG_SESSION_DESKTOP") "ewm"))
|
||||||
|
; Dynamic Tab (Workspace) Setup
|
||||||
|
(use-package tab-line
|
||||||
|
:ensure nil)
|
||||||
|
(setq tab-bar-show 1) ; Hide the bar if only 1 tab exists
|
||||||
|
(setq tab-bar-new-tab-choice "*scratch*")
|
||||||
|
|
||||||
|
(defun dynamic-tab-ensure-scratch-tab ()
|
||||||
|
"Ensures there is always a tab dedicated to *scratch*."
|
||||||
|
(let* ((tabs (funcall tab-bar-tabs-function))
|
||||||
|
(tab-names (mapcar (lambda (tab) (alist-get 'name tab)) tabs))
|
||||||
|
(spare-exists (member "dynamic *scratch*" tab-names))
|
||||||
|
(is-child-frame (frame-parent)))
|
||||||
|
|
||||||
|
;; If we are currently IN the spare tab and it's not *scratch* anymore,
|
||||||
|
;; or if we just want to ensure it exists at the end:
|
||||||
|
(unless (or spare-exists is-child-frame)
|
||||||
|
(let ((current-tab (tab-bar--current-tab-index)))
|
||||||
|
(tab-bar-new-tab 999)
|
||||||
|
(tab-bar-rename-tab "dynamic *scratch*")
|
||||||
|
;; Return to original tab if we were just initializing
|
||||||
|
(tab-bar-select-tab (1+ current-tab))))))
|
||||||
|
|
||||||
|
(defun dynamic-tab-handle-tab-persistence ()
|
||||||
|
"Create new tab if current scratch tab is being used."
|
||||||
|
(when (string= (alist-get 'name (tab-bar--current-tab)) "dynamic *scratch*")
|
||||||
|
(unless (or (string= (buffer-name) "*scratch*") (minibufferp))
|
||||||
|
;; User switched away from scratch in the spare tab, rename it
|
||||||
|
(tab-bar-rename-tab "")))
|
||||||
|
;; and create a new spare.
|
||||||
|
(dynamic-tab-ensure-scratch-tab))
|
||||||
|
|
||||||
|
(defvar already-redirecting-p nil)
|
||||||
|
(defun dynamic-tab-redirect-to-scratch-tab (&rest _)
|
||||||
|
"Redirect to dedicated scratch tab if scratch buffer accessed on other tab."
|
||||||
|
(when (and (not already-redirecting-p)
|
||||||
|
(string= (buffer-name) "*scratch*")
|
||||||
|
(not (string= (alist-get 'name (tab-bar--current-tab)) "dynamic *scratch*")))
|
||||||
|
(setq already-redirecting-p t)
|
||||||
|
(unwind-protect
|
||||||
|
(switch-to-buffer nil)
|
||||||
|
(tab-bar-select-tab-by-name "dynamic *scratch*")
|
||||||
|
(setq already-redirecting-p nil))))
|
||||||
|
|
||||||
|
(defun dynamic-tab-handle-buffer-check-and-close-tab ()
|
||||||
|
"Check if we need to close the tab and action accordingly."
|
||||||
|
(let* ((is-last-tab (<= (length (tab-bar-tabs)) 2))
|
||||||
|
(is-last-buffer (<= (length (tab-line-tabs-window-buffers)) 2)))
|
||||||
|
(when (and (not is-last-tab) is-last-buffer)
|
||||||
|
(tab-close))))
|
||||||
|
|
||||||
|
(defun dynamic-tab-handle-tab-cleanup-kill (orig-fun &rest args)
|
||||||
|
"Free tab if all reserved in use buffers for that tab killed."
|
||||||
|
(let* ((is-last-tab (<= (length (tab-bar-tabs)) 2))
|
||||||
|
(is-child-buffer (frame-parent))
|
||||||
|
(is-mini-buffer (minibufferp))
|
||||||
|
(is-dynamic-buffer (string= (alist-get 'name (tab-bar--current-tab)) "dynamic *scratch*"))
|
||||||
|
(is-scratch-buffer (string= (alist-get 'name (tab-bar--current-tab)) "*scratch*"))
|
||||||
|
(is-last-buffer (<= (length (tab-line-tabs-window-buffers)) 2))
|
||||||
|
(is-overriden (nth 1 args))
|
||||||
|
(is-target-focused (and (eq (current-buffer) (car args))))
|
||||||
|
(is-called-interactively (called-interactively-p 'any)))
|
||||||
|
|
||||||
|
(cond
|
||||||
|
((and (not is-overriden) (not is-called-interactively)) (apply orig-fun args))
|
||||||
|
(is-child-buffer nil)
|
||||||
|
(is-mini-buffer nil)
|
||||||
|
(is-dynamic-buffer nil)
|
||||||
|
(is-scratch-buffer nil)
|
||||||
|
((and (not is-overriden) is-called-interactively) (apply orig-fun (nbutlast args)))
|
||||||
|
|
||||||
|
((and is-last-tab is-last-buffer) (apply orig-fun (nbutlast args)))
|
||||||
|
((and is-last-tab (not is-last-buffer)) (apply orig-fun (nbutlast args)))
|
||||||
|
;((and is-last-tab (not is-last-buffer) (bury-buffer)))
|
||||||
|
|
||||||
|
((and (not is-last-tab) (not is-last-buffer) (bury-buffer)))
|
||||||
|
|
||||||
|
(t nil))
|
||||||
|
|
||||||
|
(when (and (not is-overriden) is-target-focused)
|
||||||
|
(dynamic-tab-handle-buffer-check-and-close-tab))))
|
||||||
|
|
||||||
|
(defun dynamic-tab-handle-tab-cleanup-close (&rest _)
|
||||||
|
"Free tab if last window open is attempted to be closed."
|
||||||
|
(if (and (> (length (tab-bar-tabs)) 2)
|
||||||
|
(= (length (window-list)) 1)
|
||||||
|
(not (string= (alist-get 'name (tab-bar--current-tab)) "dynamic *scratch*")))
|
||||||
|
(tab-close)
|
||||||
|
t))
|
||||||
|
|
||||||
|
;; Helper functions for EWM
|
||||||
|
; Switch monitor
|
||||||
|
(defun ewm-switch-to-monitor (target)
|
||||||
|
(interactive)
|
||||||
|
(select-frame-set-input-focus (car (last (seq-filter (lambda (f)
|
||||||
|
(string= target
|
||||||
|
(cdr (assq 'name (frame-monitor-attributes f)))))
|
||||||
|
(frame-list))))))
|
||||||
|
|
||||||
|
; EWM - Emacs Wayland Manager
|
||||||
|
(use-package ewm
|
||||||
|
:ensure nil
|
||||||
|
:custom
|
||||||
|
(ewm-output-config
|
||||||
|
'(("DP-1"
|
||||||
|
:width 1920
|
||||||
|
:height 1080
|
||||||
|
:scale 1.0
|
||||||
|
:x 0
|
||||||
|
:y 0
|
||||||
|
:refresh 240)
|
||||||
|
("HDMI-A-1"
|
||||||
|
:width 1920
|
||||||
|
:height 1080
|
||||||
|
:scale 1.0
|
||||||
|
:x 1920
|
||||||
|
:y 0
|
||||||
|
:transform 3
|
||||||
|
:refresh 75)))
|
||||||
|
(ewm-input-config
|
||||||
|
'((touchpad :natural-scroll t :tap t :dwt t)
|
||||||
|
(mouse :accel-profile "flat")
|
||||||
|
(keyboard :repeat-delay 150 :repeat-rate 35
|
||||||
|
:xkb-layouts "gb")))
|
||||||
|
;; Per-device override (exact name from libinput)
|
||||||
|
;("ELAN0676:00 04F3:3195 Touchpad" :tap nil :accel-speed -0.2)))
|
||||||
|
:bind (:map ewm-mode-map
|
||||||
|
("M-d" . ewm-launch-app)
|
||||||
|
("s-l" . ewm-lock-session)
|
||||||
|
("M-<return>" . eshell)
|
||||||
|
("<print>" . (lambda ()
|
||||||
|
(interactive)
|
||||||
|
(start-process-shell-command
|
||||||
|
"screenshot-process"
|
||||||
|
nil
|
||||||
|
"grim -g \"$(slurp)\" - | wl-copy")))
|
||||||
|
("M-w" . (lambda ()
|
||||||
|
(interactive)
|
||||||
|
(kill-buffer)))
|
||||||
|
|
||||||
|
; Monitor switching, find current focused monitor name via
|
||||||
|
;(cdr (assq 'name (frame-monitor-attributes))
|
||||||
|
("M-o" . (lambda ()
|
||||||
|
(interactive)
|
||||||
|
(ewm-switch-to-monitor "XG2431")))
|
||||||
|
("M-p" . (lambda ()
|
||||||
|
(interactive)
|
||||||
|
(ewm-switch-to-monitor "24B2W1G5")))
|
||||||
|
|
||||||
|
;;("M-f" . (lambda ()
|
||||||
|
;; (interactive)
|
||||||
|
;; (start-process-shell-command
|
||||||
|
;; "wlkbptr-process"
|
||||||
|
;; nil
|
||||||
|
;; "wl-kbptr -o modes=floating,click -o mode_floating.source=detect"))
|
||||||
|
|
||||||
|
("M-h" . tab-bar-switch-to-prev-tab)
|
||||||
|
("M-l" . tab-bar-switch-to-next-tab)
|
||||||
|
("M-k" . windmove-up)
|
||||||
|
("M-j" . windmove-down))
|
||||||
|
:config
|
||||||
|
(add-to-list 'ewm-intercept-prefixes ?\M-d)
|
||||||
|
(add-to-list 'ewm-intercept-prefixes ?\M-w)
|
||||||
|
(add-to-list 'ewm-intercept-prefixes ?\M-o)
|
||||||
|
(add-to-list 'ewm-intercept-prefixes ?\M-p)
|
||||||
|
(add-to-list 'ewm-intercept-prefixes ?\M-h)
|
||||||
|
(add-to-list 'ewm-intercept-prefixes ?\M-j)
|
||||||
|
(add-to-list 'ewm-intercept-prefixes ?\M-k)
|
||||||
|
(add-to-list 'ewm-intercept-prefixes ?\M-l)
|
||||||
|
:init
|
||||||
|
;; Dynamic Tabs/Workspaces setup
|
||||||
|
; Hooks
|
||||||
|
(advice-add 'consult-buffer
|
||||||
|
:after (lambda (&rest _)
|
||||||
|
(dynamic-tab-handle-tab-persistence)
|
||||||
|
(dynamic-tab-redirect-to-scratch-tab)))
|
||||||
|
(advice-add 'delete-window :before-while #'dynamic-tab-handle-tab-cleanup-close)
|
||||||
|
(advice-add 'kill-buffer :around #'dynamic-tab-handle-tab-cleanup-kill)
|
||||||
|
;(add-hook 'buffer-list-update-hook #'dynamic-tab-redirect-to-scratch-tab)
|
||||||
|
(add-hook 'window-configuration-change-hook #'dynamic-tab-handle-tab-persistence)
|
||||||
|
; Initialize on startup
|
||||||
|
(dynamic-tab-ensure-scratch-tab))
|
||||||
|
|
||||||
|
; Desktop notifications in Emacs
|
||||||
|
(use-package ednc
|
||||||
|
:ensure t
|
||||||
|
:init
|
||||||
|
(ednc-mode)))
|
||||||
|
;(use-package ednc-popup
|
||||||
|
; :ensure (:host git :repo "https://codeberg.org/akib/emacs-ednc-popup.git")
|
||||||
|
; :after ednc
|
||||||
|
; :config
|
||||||
|
; (add-hook 'ednc-notification-presentation-functions
|
||||||
|
; #'ednc-popup-presentation-function))
|
||||||
|
|
||||||
(custom-set-variables
|
(custom-set-variables
|
||||||
;; custom-set-variables was added by Custom.
|
;; custom-set-variables was added by Custom.
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue