jao-afio.el 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. ;;; jao-afio.el --- workspaces in just one frame -*- lexical-binding: t; -*-
  2. ;; Copyright (C) 2020, 2021, 2022, 2024 jao
  3. ;; Author: jao <mail@jao.io>
  4. ;; Keywords: frames
  5. ;; This program is free software; you can redistribute it and/or modify
  6. ;; it under the terms of the GNU General Public License as published by
  7. ;; the Free Software Foundation, either version 3 of the License, or
  8. ;; (at your option) any later version.
  9. ;; This program is distributed in the hope that it will be useful,
  10. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. ;; GNU General Public License for more details.
  13. ;; You should have received a copy of the GNU General Public License
  14. ;; along with this program. If not, see <https://www.gnu.org/licenses/>.
  15. ;;; initialisation
  16. (require 'cl-lib)
  17. (require 'jao-doc-session)
  18. (defvar jao-afio-use-frames (not window-system))
  19. (defvar jao-open-doc-fun 'find-file)
  20. (defvar jao-afio-mail-function 'gnus)
  21. (defvar jao-afio-use-w3m nil)
  22. (defvar jao-afio-auto-toggle nil)
  23. (defvar jao-afio-switch-hook nil)
  24. (defvar jao-afio--configs '(?c ?w ?g ?p ?s ?t))
  25. (defvar jao-afio--previous-config (car jao-afio--configs))
  26. (defun jao-afio--current-config (&optional c f)
  27. (when c (modify-frame-parameters f `((afio . ,c))))
  28. (frame-parameter f 'afio))
  29. (defun jao-afio--init (&optional f)
  30. (interactive)
  31. (jao-afio--current-config ?c)
  32. (if jao-afio-use-frames
  33. (set-frame-name "W1")
  34. (window-configuration-to-register ?c)))
  35. (defun jao-afio--check-frame ()
  36. (unless (jao-afio--current-config)
  37. (jao-afio--init (window-frame (get-buffer-window (current-buffer))))))
  38. ;;; utilities
  39. (defun jao-afio-trisect (&optional force)
  40. (interactive)
  41. (let ((fw (frame-width))
  42. (display-buffer-alist nil))
  43. (cond ((or force (>= fw 240))
  44. (let ((b (current-buffer)))
  45. (delete-other-windows)
  46. (switch-to-buffer (other-buffer b))
  47. (split-window-horizontally)
  48. (switch-to-buffer (other-buffer b))
  49. (split-window-horizontally)
  50. (switch-to-buffer b)
  51. (balance-windows)))
  52. ((> fw 162)
  53. (delete-other-windows)
  54. (split-window-horizontally)
  55. (switch-to-buffer (other-buffer))))))
  56. ;;; session openers
  57. ;;;###autoload
  58. (defun jao-afio-open-pdf-session (&optional docs)
  59. (interactive)
  60. (let ((jao-doc-session-inhibit-save t))
  61. (dolist (doc (or docs (jao-doc-session)))
  62. (when (and doc (file-exists-p doc))
  63. (if (jao-pdf-is-pdf-file doc) (jao-open-doc doc) (find-file doc))
  64. (other-window 1)))
  65. (other-window 1)))
  66. (defun jao-afio-open-doc ()
  67. (interactive)
  68. (delete-other-windows)
  69. (split-window-right)
  70. (let ((docs (cl-remove-if-not 'jao-doc-session-is-doc (buffer-list))))
  71. (if (car docs)
  72. (progn (switch-to-buffer (car docs))
  73. (switch-to-buffer-other-window (or (cadr docs) (car docs))))
  74. (when-let (docs (jao-doc-session))
  75. (when (y-or-n-p (format "Load saved session? (%d docs)" (length docs)))
  76. (jao-afio-open-pdf-session docs))))))
  77. (declare-function w3m "w3m")
  78. (declare-function notmuch "notmuch")
  79. (declare-function jao-eww-session-eww-buffers "jao-eww-session")
  80. (declare-function jao-eww-session-load "jao-eww-session")
  81. (defun jao-afio--open-eww-session ()
  82. (if-let (b (jao-eww-session-eww-buffers))
  83. (switch-to-buffer (car b))
  84. (jao-eww-session-load)))
  85. ;;;###autoload
  86. (defun jao-afio-open-www ()
  87. (interactive)
  88. (require 'jao-eww-session)
  89. (if (< (frame-width) 160)
  90. (if jao-afio-use-w3m (w3m) (jao-afio--open-eww-session))
  91. (if jao-afio-use-w3m
  92. (progn (delete-other-windows)
  93. (split-window-right)
  94. (w3m))
  95. (jao-afio-trisect)
  96. (jao-afio--open-eww-session)
  97. (let ((b (current-buffer)))
  98. (other-window 1)
  99. (switch-to-buffer (car (jao-eww-session-eww-buffers b)))
  100. (other-window 1)
  101. (switch-to-buffer (car (jao-eww-session-eww-buffers b)))
  102. (other-window 1)))))
  103. ;;;###autoload
  104. (defun jao-afio-open-gnus ()
  105. (interactive)
  106. (delete-other-windows)
  107. (jao-org-agenda)
  108. (calendar)
  109. (find-file (expand-file-name "inbox.org" org-directory))
  110. (gnus)
  111. (jao-gnus--set-summary-line))
  112. (defun jao-afio--mail-sidebar ()
  113. (other-window 1)
  114. (delete-other-windows-vertically)
  115. (find-file (expand-file-name "inbox.org" org-directory))
  116. (set-window-dedicated-p nil t)
  117. (split-window-below (/ (window-height) 3))
  118. (other-window 1)
  119. (jao-org-agenda)
  120. (set-window-dedicated-p nil t)
  121. (split-window-below -8)
  122. (other-window 1)
  123. (switch-to-buffer "*Calendar*")
  124. (set-window-dedicated-p nil t)
  125. (other-window 1))
  126. (defun jao-afio--open-mail (fun)
  127. (unless (get-buffer "*Calendar*") (calendar))
  128. (delete-other-windows)
  129. (split-window-horizontally -80)
  130. (funcall fun)
  131. ;; (set-window-dedicated-p nil t)
  132. (jao-afio--mail-sidebar))
  133. ;;;###autoload
  134. (defun jao-afio-open-mail ()
  135. (interactive)
  136. (cond ((eq 'gnus jao-afio-mail-function) (jao-afio-open-gnus))
  137. ((eq 'notmuch jao-afio-mail-function) (jao-afio--open-mail 'notmuch))
  138. (t (jao-afio-trisect))))
  139. ;;;###autoload
  140. (defun jao-afio-reset ()
  141. (interactive)
  142. (delete-other-windows)
  143. (cl-case (jao-afio--current-config)
  144. (?w (jao-afio-open-www))
  145. (?g (jao-afio-open-mail))
  146. (?p (jao-afio-open-doc))
  147. (t (jao-afio-trisect))))
  148. ;;; go to frame
  149. (defsubst jao-afio--find-frame (c)
  150. (seq-find (lambda (f) (eq (jao-afio--current-config nil f) c)) (frame-list)))
  151. (defun jao-afio-frame-name (&optional c)
  152. (alist-get (or c (jao-afio--current-config))
  153. '((?c . "main") (?s . "scratch") (?g . "mail")
  154. (?p . "docs") (?w . "web") (?t . "chats"))))
  155. (defun jao-afio-frame-no (&optional c)
  156. (alist-get (or c (jao-afio--current-config))
  157. '((?s . 0) (?c . 1) (?g . 2) (?w . 3) (?p . 4) (?t . 5))))
  158. (defun jao-afio--goto-frame (next &optional reset)
  159. (jao-afio--check-frame)
  160. (let ((current (jao-afio--current-config)))
  161. (if (and jao-afio-auto-toggle
  162. (eq next current)
  163. (not reset)
  164. (not (eq current jao-afio--previous-config)))
  165. (jao-afio--goto-frame jao-afio--previous-config)
  166. (when (or reset (not (eq next current)))
  167. (if jao-afio-use-frames
  168. (let ((f (jao-afio--find-frame next)))
  169. (select-frame-set-input-focus (or f (make-frame)))
  170. (when (setq reset (or reset (not f)))
  171. (set-frame-name
  172. (format "W%s" (or (jao-afio-frame-no next) next)))))
  173. (window-configuration-to-register (jao-afio--current-config))
  174. (when (and (not reset) (get-register next))
  175. (ignore-errors (jump-to-register next)))
  176. (setq reset (or reset (not (get-register next)))))
  177. (jao-afio--current-config next)
  178. (unless (eq current next) (setq jao-afio--previous-config current))
  179. (when reset (jao-afio-reset))
  180. (run-hooks 'jao-afio-switch-hook)))))
  181. (defun jao-afio-goto-main (&optional reset)
  182. (interactive "P")
  183. (jao-afio--goto-frame ?c reset))
  184. (defun jao-afio-goto-mail (&optional reset)
  185. (interactive "P")
  186. (jao-afio--goto-frame ?g reset))
  187. (defun jao-afio-goto-docs (&optional reset)
  188. (interactive "P")
  189. (jao-afio--goto-frame ?p reset))
  190. (defun jao-afio-goto-www (&optional reset)
  191. (interactive "P")
  192. (jao-afio--goto-frame ?w reset))
  193. (defun jao-afio-toggle ()
  194. (interactive)
  195. (jao-afio--goto-frame jao-afio--previous-config))
  196. (defun jao-afio-goto-scratch (&optional one-win)
  197. (interactive "P")
  198. (jao-afio--goto-frame ?s nil)
  199. (when one-win (delete-other-windows)))
  200. (defun jao-afio-goto-chats (&optional reset)
  201. (interactive "P")
  202. (jao-afio--goto-frame ?t reset))
  203. ;;;###autoload
  204. (defun jao-afio-goto-nth (n)
  205. (cl-case n
  206. ((-1) (jao-afio-goto-scratch t))
  207. ((0) (jao-afio-goto-scratch))
  208. ((1) (jao-afio-goto-main))
  209. ((2) (jao-afio-goto-mail))
  210. ((3) (jao-afio-goto-www))
  211. ((4) (jao-afio-goto-docs))
  212. ((5) (jao-afio-goto-chats))))
  213. ;;;###autoload
  214. (defun jao-afio-pop-to-buffer (n buff)
  215. (interactive "NFrame number: \nBBuffer: ")
  216. (jao-afio-goto-nth n)
  217. (pop-to-buffer buff))
  218. ;;; setup
  219. ;;;###autoload
  220. (defun jao-afio-setup (&optional use-frames)
  221. (setq jao-afio-use-frames use-frames)
  222. (jao-afio--init))
  223. (provide 'jao-afio)
  224. ;;; jao-afio.el ends here