;;; exwm-buffer-groups.el --- Buffer grouping for EXWM workspaces. -*- lexical-binding: t; -*- ;; Copyright (C) 2019 Jakob L. Kreuze ;; Author: Jakob L. Kreuze ;; Version: 1.0 ;; Package-Requires (cl-lib exwm) ;; Keywords: frames ;; URL: https://git.sr.ht/~jakob/exwm-buffer-groups ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation, either version 3 of the License, or ;; (at your option) any later version. ;; This program is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License ;; along with this program. If not, see . ;;; Commentary: ;; The default behavior of EXWM is to make buffers containing X windows ;; accessible only from the workspace they were created in. This is a useful ;; feature, but introduces some level of inconsistency as this does not apply to ;; normal buffers. exwm-buffer-groups aims to change this by associating all ;; buffers with a workspace. ;;; Code: (require 'cl-lib) (require 'exwm) (defun exwm-buffer-groups-default-buffers () "Initial list of buffers for a workspace." (if (get-buffer "*scratch*") (list (get-buffer "*scratch*")) nil)) (defvar exwm-buffer-groups-buffers (make-vector exwm-workspace-number (exwm-buffer-groups-default-buffers)) "Vector containing lists of associated buffers for each workspace.") (defun exwm-buffer-groups--buffer-seen-p (buffer) "Whether or not BUFFER is contained in `exwm-buffer-groups-buffers'." (reduce #'(lambda (x y) (or x y)) (map 'list #'(lambda (workspace) (memq buffer workspace)) exwm-buffer-groups-buffers))) (defun exwm-buffer-groups--remove-buffers () "Removes dead buffers from `exwm-buffer-groups-buffers'." (setq exwm-buffer-groups-buffers (map 'vector #'(lambda (buffers) (cl-remove-if-not #'buffer-live-p buffers)) exwm-buffer-groups-buffers))) (defun exwm-buffer-groups--add-buffers () "Adds unseen buffers to `exwm-buffer-groups-buffers'. Any unseen buffers are added to the entry corresponding to the current workspace." (dolist (buffer (buffer-list)) (unless (exwm-buffer-groups--buffer-seen-p buffer) (push buffer (elt exwm-buffer-groups-buffers exwm-workspace-current-index))))) (defun exwm-buffer-groups-update () "Updates `exwm-buffer-groups-buffers' to reflect the buffer list." (exwm-buffer-groups--remove-buffers) (exwm-buffer-groups--add-buffers)) (defun exwm-buffer-groups-switch-buffer (buffer-or-name) "Display buffer BUFFER-OR-NAME in the selected window. If called interactively, read the buffer name using `completing-read', completing only on buffers in the current workspace." (interactive (list (let ((buffers-in-workspace (map 'list #'buffer-name (elt exwm-buffer-groups-buffers exwm-workspace-current-index))) (current-buffer (buffer-name (other-buffer (current-buffer))))) (completing-read "Switch to buffer: " buffers-in-workspace nil nil nil nil current-buffer)))) (switch-to-buffer buffer-or-name)) (defun exwm-buffer-groups-move (nth) "Moves the current buffer to the NTH workspace." (interactive (list (exwm-workspace--position (exwm-workspace--prompt-for-workspace "Move workspace to: ")))) ;; Remove the buffer from the current workspace. (setf (elt exwm-buffer-groups-buffers exwm-workspace-current-index) (remove (current-buffer) (elt exwm-buffer-groups-buffers exwm-workspace-current-index))) ;; Add it to the NTH workspace. (push (current-buffer) (elt exwm-buffer-groups-buffers nth)) ;; Switch out of the buffer. (set-window-dedicated-p nil nil) (switch-to-prev-buffer nil 'bury)) (add-hook 'after-change-major-mode-hook #'exwm-buffer-groups-update) (provide 'exwm-buffer-groups) ;;; exwm-buffer-groups.el ends here