emacs/org/elpa/0blayout-20190703.527/0blayout.el
2024-07-28 12:03:37 -04:00

201 lines
6 KiB
EmacsLisp

;;; 0blayout.el --- Layout grouping with ease
;; Copyright (c) 2015-2016 Elis Axelsson
;; Author: Elis "etu" Axelsson
;; URL: https://github.com/etu/0blayout
;; Package-Version: 20160918.0
;; Version: 1.0.2
;; Keywords: convenience, window-management
;;; Commentary:
;; This global minor mode provides a simple way to switch between layouts and
;; the buffers you left open before you switched (unless you closed it).
;; It doesn't require any setup at all more than:
;; (0blayout-mode)
;; When you start Emacs with 0blayout loaded, you will have a default layout
;; named "default", and then you can create new layouts (<prefix> C-c), switch
;; layouts (<prefix> C-b), and kill the current layout (<prefix> C-k).
;; The default <prefix> is (C-c C-l), but you can change it using:
;; (0blayout-add-keybindings-with-prefix "<your prefix>")
;; You can also customize-variable to change the name of the default session.
;; The project is hosted at https://github.com/etu/0blayout
;; There you can leave bug-reports and suggestions.
;; Another comparable mode is eyebrowse which have been developed for longer.
;;; License:
;; This file 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 file 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 file; if not, write to the Free Software
;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
;; 02110-1301, USA.
;;; Code:
(defgroup 0blayout nil
"Configuration settings for 0blayout-mode."
:group 'convenience)
(defvar 0blayout-alist ()
"List of the currently defined layouts.")
(defcustom 0blayout-default "default"
"Name of default layout used."
:type 'string
:group '0blayout)
(defvar 0blayout-keys-map '(("C-c" . 0blayout-new)
("C-k" . 0blayout-kill)
("C-b" . 0blayout-switch))
"Which keys bounded to which functions map.")
(defvar 0blayout-mode-map (make-sparse-keymap)
"Keymap for 0blayout.")
;; Function to create a new layout
(defun 0blayout-new (layout-name)
"0blayout creating function.
Argument LAYOUT-NAME Name of the layout."
(interactive "sEnter name of new layout: ")
;; Save the currently active layout
(0blayout-save)
;; Then we just delete all other windows and switch to a *scratch* buffer,
;; then it's up to the user to set up their layout.
(delete-other-windows)
(switch-to-buffer "*scratch*")
;; Save the name of the new current layout
(0blayout-set-current-name layout-name))
;; Function to kill current layout
(defun 0blayout-kill ()
"0blayout removal function."
(interactive)
(message "Killing layout: '%s'" (0blayout-get-current-name))
;; Remove current layout from known layouts
(setq 0blayout-alist
(assq-delete-all (intern (0blayout-get-current-name)) 0blayout-alist))
;; Switch to next layout in the list
(let ((new-layout (car (car 0blayout-alist))))
(if (eq new-layout nil)
;; If there's no other layout, make a new default layout
(progn
(0blayout-set-current-name 0blayout-default)
(0blayout-new 0blayout-default))
;; Switch to some other saved layout
(progn
(set-window-configuration (cdr (car 0blayout-alist)))
(0blayout-set-current-name (symbol-name new-layout))))))
;; Function to switch layout
(defun 0blayout-switch (layout-name)
"0blayout switching function.
Argument LAYOUT-NAME Name of the layout."
(interactive
(list
(completing-read "Layout to switch to: " 0blayout-alist)))
;; Save the currently active layout
(0blayout-save)
(let ((layout (assoc (intern layout-name) 0blayout-alist)))
(if (eq layout nil)
(message "No layout with name: '%s' is defined" layout-name)
(progn
;; Load window configuration
(set-window-configuration (cdr layout))
;; Save the name of the currently active layout
(0blayout-set-current-name layout-name)
(message "Switch to layout: '%s'" layout-name)))))
;; Function to save layout
(defun 0blayout-save ()
"This is a helper function to save the current layout."
;; Remove all saves of current layout before saving
(setq 0blayout-alist
(assq-delete-all
(intern (0blayout-get-current-name)) 0blayout-alist))
;; Add current layout to list
(add-to-list '0blayout-alist
(cons (intern (0blayout-get-current-name))
(current-window-configuration)))
(message "Saved the currently active layout: %s" (0blayout-get-current-name)))
;; Save current layout name
(defun 0blayout-set-current-name (layout-name)
"Helper function to store current LAYOUT-NAME for this frame."
(set-frame-parameter nil '0blayout-current layout-name))
;; Get current layout name
(defun 0blayout-get-current-name ()
"Helper function to get current LAYOUT-NAME for this frame."
;; Get variable from current frame
(let ((current-layout (frame-parameter nil '0blayout-current)))
;; Check if it's nil
(if (eq current-layout nil)
;; If so, return default value
0blayout-default
;; else return current value
current-layout)))
;;;###autoload
(defun 0blayout-add-keybindings-with-prefix (prefix)
"Add 0blayout keybindings using the prefix PREFIX."
(setf (cdr 0blayout-mode-map) nil)
(dolist (pair 0blayout-keys-map)
(define-key 0blayout-mode-map
(kbd (format "%s %s" prefix (car pair)))
(cdr pair))))
(0blayout-add-keybindings-with-prefix "C-c C-l")
;;;###autoload
(define-minor-mode 0blayout-mode
"Handle layouts with ease"
:lighter " 0bL"
:global t
:group '0blayout
:keymap 0blayout-mode-map)
(provide '0blayout)
;;; 0blayout.el ends here