;;; jao-afio.el --- workspaces in just one frame -*- lexical-binding: t; -*- ;; Copyright (C) 2020, 2021, 2022, 2024 jao ;; Author: jao ;; Keywords: frames ;; 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 . ;;; initialisation (require 'cl-lib) (require 'jao-doc-session) (defvar jao-afio-use-frames (not window-system)) (defvar jao-open-doc-fun 'find-file) (defvar jao-afio-mail-function 'gnus) (defvar jao-afio-use-w3m nil) (defvar jao-afio-auto-toggle nil) (defvar jao-afio-switch-hook nil) (defvar jao-afio--configs '(?c ?w ?g ?p ?s ?t)) (defvar jao-afio--previous-config (car jao-afio--configs)) (defun jao-afio--current-config (&optional c f) (when c (modify-frame-parameters f `((afio . ,c)))) (frame-parameter f 'afio)) (defun jao-afio--init (&optional f) (interactive) (jao-afio--current-config ?c) (if jao-afio-use-frames (set-frame-name "W1") (window-configuration-to-register ?c))) (defun jao-afio--check-frame () (unless (jao-afio--current-config) (jao-afio--init (window-frame (get-buffer-window (current-buffer)))))) ;;; utilities (defun jao-afio-trisect (&optional force) (interactive) (let ((fw (frame-width)) (display-buffer-alist nil)) (cond ((or force (>= fw 240)) (let ((b (current-buffer))) (delete-other-windows) (switch-to-buffer (other-buffer b)) (split-window-horizontally) (switch-to-buffer (other-buffer b)) (split-window-horizontally) (switch-to-buffer b) (balance-windows))) ((> fw 162) (delete-other-windows) (split-window-horizontally) (switch-to-buffer (other-buffer)))))) ;;; session openers ;;;###autoload (defun jao-afio-open-pdf-session (&optional docs) (interactive) (let ((jao-doc-session-inhibit-save t)) (dolist (doc (or docs (jao-doc-session))) (when (and doc (file-exists-p doc)) (if (jao-pdf-is-pdf-file doc) (jao-open-doc doc) (find-file doc)) (other-window 1))) (other-window 1))) (defun jao-afio-open-doc () (interactive) (delete-other-windows) (split-window-right) (let ((docs (cl-remove-if-not 'jao-doc-session-is-doc (buffer-list)))) (if (car docs) (progn (switch-to-buffer (car docs)) (switch-to-buffer-other-window (or (cadr docs) (car docs)))) (when-let (docs (jao-doc-session)) (when (y-or-n-p (format "Load saved session? (%d docs)" (length docs))) (jao-afio-open-pdf-session docs)))))) (declare-function w3m "w3m") (declare-function notmuch "notmuch") (declare-function jao-eww-session-eww-buffers "jao-eww-session") (declare-function jao-eww-session-load "jao-eww-session") (defun jao-afio--open-eww-session () (if-let (b (jao-eww-session-eww-buffers)) (switch-to-buffer (car b)) (jao-eww-session-load))) ;;;###autoload (defun jao-afio-open-www () (interactive) (require 'jao-eww-session) (if (< (frame-width) 160) (if jao-afio-use-w3m (w3m) (jao-afio--open-eww-session)) (if jao-afio-use-w3m (progn (delete-other-windows) (split-window-right) (w3m)) (jao-afio-trisect) (jao-afio--open-eww-session) (let ((b (current-buffer))) (other-window 1) (switch-to-buffer (car (jao-eww-session-eww-buffers b))) (other-window 1) (switch-to-buffer (car (jao-eww-session-eww-buffers b))) (other-window 1))))) ;;;###autoload (defun jao-afio-open-gnus () (interactive) (delete-other-windows) (jao-org-agenda) (calendar) (find-file (expand-file-name "inbox.org" org-directory)) (gnus) (jao-gnus--set-summary-line)) (defun jao-afio--mail-sidebar () (other-window 1) (delete-other-windows-vertically) (find-file (expand-file-name "inbox.org" org-directory)) (set-window-dedicated-p nil t) (split-window-below (/ (window-height) 3)) (other-window 1) (jao-org-agenda) (set-window-dedicated-p nil t) (split-window-below -8) (other-window 1) (switch-to-buffer "*Calendar*") (set-window-dedicated-p nil t) (other-window 1)) (defun jao-afio--open-mail (fun) (unless (get-buffer "*Calendar*") (calendar)) (delete-other-windows) (split-window-horizontally -80) (funcall fun) ;; (set-window-dedicated-p nil t) (jao-afio--mail-sidebar)) ;;;###autoload (defun jao-afio-open-mail () (interactive) (cond ((eq 'gnus jao-afio-mail-function) (jao-afio-open-gnus)) ((eq 'notmuch jao-afio-mail-function) (jao-afio--open-mail 'notmuch)) (t (jao-afio-trisect)))) ;;;###autoload (defun jao-afio-reset () (interactive) (delete-other-windows) (cl-case (jao-afio--current-config) (?w (jao-afio-open-www)) (?g (jao-afio-open-mail)) (?p (jao-afio-open-doc)) (t (jao-afio-trisect)))) ;;; go to frame (defsubst jao-afio--find-frame (c) (seq-find (lambda (f) (eq (jao-afio--current-config nil f) c)) (frame-list))) (defun jao-afio-frame-name (&optional c) (alist-get (or c (jao-afio--current-config)) '((?c . "main") (?s . "scratch") (?g . "mail") (?p . "docs") (?w . "web") (?t . "chats")))) (defun jao-afio-frame-no (&optional c) (alist-get (or c (jao-afio--current-config)) '((?s . 0) (?c . 1) (?g . 2) (?w . 3) (?p . 4) (?t . 5)))) (defun jao-afio--goto-frame (next &optional reset) (jao-afio--check-frame) (let ((current (jao-afio--current-config))) (if (and jao-afio-auto-toggle (eq next current) (not reset) (not (eq current jao-afio--previous-config))) (jao-afio--goto-frame jao-afio--previous-config) (when (or reset (not (eq next current))) (if jao-afio-use-frames (let ((f (jao-afio--find-frame next))) (select-frame-set-input-focus (or f (make-frame))) (when (setq reset (or reset (not f))) (set-frame-name (format "W%s" (or (jao-afio-frame-no next) next))))) (window-configuration-to-register (jao-afio--current-config)) (when (and (not reset) (get-register next)) (ignore-errors (jump-to-register next))) (setq reset (or reset (not (get-register next))))) (jao-afio--current-config next) (unless (eq current next) (setq jao-afio--previous-config current)) (when reset (jao-afio-reset)) (run-hooks 'jao-afio-switch-hook))))) (defun jao-afio-goto-main (&optional reset) (interactive "P") (jao-afio--goto-frame ?c reset)) (defun jao-afio-goto-mail (&optional reset) (interactive "P") (jao-afio--goto-frame ?g reset)) (defun jao-afio-goto-docs (&optional reset) (interactive "P") (jao-afio--goto-frame ?p reset)) (defun jao-afio-goto-www (&optional reset) (interactive "P") (jao-afio--goto-frame ?w reset)) (defun jao-afio-toggle () (interactive) (jao-afio--goto-frame jao-afio--previous-config)) (defun jao-afio-goto-scratch (&optional one-win) (interactive "P") (jao-afio--goto-frame ?s nil) (when one-win (delete-other-windows))) (defun jao-afio-goto-chats (&optional reset) (interactive "P") (jao-afio--goto-frame ?t reset)) ;;;###autoload (defun jao-afio-goto-nth (n) (cl-case n ((-1) (jao-afio-goto-scratch t)) ((0) (jao-afio-goto-scratch)) ((1) (jao-afio-goto-main)) ((2) (jao-afio-goto-mail)) ((3) (jao-afio-goto-www)) ((4) (jao-afio-goto-docs)) ((5) (jao-afio-goto-chats)))) ;;;###autoload (defun jao-afio-pop-to-buffer (n buff) (interactive "NFrame number: \nBBuffer: ") (jao-afio-goto-nth n) (pop-to-buffer buff)) ;;; setup ;;;###autoload (defun jao-afio-setup (&optional use-frames) (setq jao-afio-use-frames use-frames) (jao-afio--init)) (provide 'jao-afio) ;;; jao-afio.el ends here