mirror of https://github.com/Chizi123/.emacs.d.git

Chizi123
2018-11-18 76bbd07de7add0f9d13c6914f158d19630fe2f62
commit | author | age
76bbd0 1 ;;; golden-ratio.el --- Automatic resizing of Emacs windows to the golden ratio
C 2
3 ;; Copyright (C) 2012 Roman Gonzalez
4
5 ;; Author: Roman Gonzalez <romanandreg@gmail.com>
6 ;; Mantainer: Roman Gonzalez <romanandreg@gmail.com>
7 ;; Created: 13 Oct 2012
8 ;; Keywords: Window Resizing
9 ;; Package-Version: 20150819.1120
10 ;; Version: 0.0.4
11
12 ;; Code inspired by ideas from Tatsuhiro Ujihisa
13
14 ;; This file is not part of GNU Emacs.
15
16 ;; This file is free software (MIT License)
17
18 ;;; Code:
19 (eval-when-compile (require 'cl))
20
21 (defconst golden-ratio--value 1.618
22   "The golden ratio value itself.")
23
24 (defgroup golden-ratio nil
25   "Resize windows to golden ratio."
26   :group 'windows)
27
28 ;; Major modes that are exempt from being resized. An example of this
29 ;; for users of Org-mode might be:
30 ;;  ("calendar-mode") or (calendar-mode)
31 (defcustom golden-ratio-exclude-modes nil
32   "A list of symbols or strings naming major modes.
33 Switching to a buffer whose major mode is a member of this list
34 will not cause the window to be resized to the golden ratio."
35   :type '(repeat (choice symbol string))
36   :group 'golden-ratio)
37
38 ;; Buffer names that are exempt from being resized. An example of this
39 ;; for users of Org-mode might be (note the leading spaces):
40 ;;  (" *Org tags*" " *Org todo*")
41 (defcustom golden-ratio-exclude-buffer-names nil
42   "An array of strings containing buffer names.
43 Switching to a buffer whose name is a member of this list
44 will not cause the window to be resized to the golden ratio."
45   :type '(repeat string)
46   :group 'golden-ratio)
47
48 (defcustom golden-ratio-inhibit-functions nil
49   "List of functions to call with no arguments.
50 Switching to a buffer, if any of these functions returns non-nil
51 will not cause the window to be resized to the golden ratio."
52   :group 'golden-ratio
53   :type '(repeat symbol))
54
55 (defcustom golden-ratio-extra-commands
56   '(windmove-left windmove-right windmove-down windmove-up)
57   "List of extra commands used to jump to other window."
58   :group 'golden-ratio
59   :type '(repeat symbol))
60
61 (defcustom golden-ratio-recenter nil
62   "Recenter window vertically and scroll right when non--nil."
63   :group 'golden-ratio
64   :type 'boolean)
65
66 (defcustom golden-ratio-adjust-factor 1.0
67   "Adjust the width sizing by some factor. 1 is no adjustment.
68    For very wide screens/frames, ie. 3400px, .4 may work well."
69   :group 'golden-ratio
70   :type 'integer)
71
72 (defcustom golden-ratio-wide-adjust-factor 0.8
73   "Width adjustment factor for widescreens. Used when
74    toggling between widescreen and regular modes."
75   :group 'golden-ratio
76   :type 'float)
77
78 (defcustom golden-ratio-auto-scale nil
79   "Automatic width adjustment factoring. Scales the width
80    of the screens to be smaller as the frame gets bigger."
81   :group 'golden-ratio
82   :type 'boolean)
83
84 (defcustom golden-ratio-exclude-buffer-regexp nil
85   "A list of regexp's used to match buffer names.
86 Switching to a buffer whose name matches one of these regexps
87 will prevent the window to be resized to the golden ratio."
88   :type '(repeat string)
89   :group 'golden-ratio)
90
91 ;;; Compatibility
92 ;;
93 (unless (fboundp 'window-resizable-p)
94   (defalias 'window-resizable-p 'window--resizable-p))
95
96 (defun golden-ratio-toggle-widescreen ()
97   (interactive)
98   (if (= golden-ratio-adjust-factor 1)
99       (setq golden-ratio-adjust-factor golden-ratio-wide-adjust-factor)
100     (setq golden-ratio-adjust-factor 1))
101   (golden-ratio))
102
103 (defun golden-ratio-adjust (a)
104   "set the adjustment of window widths."
105   (interactive
106    (list
107     (read-number "Screeen width adjustment factor: " golden-ratio-adjust-factor)))
108   (setq golden-ratio-adjust-factor a)
109   (golden-ratio))
110
111 (defun golden-ratio--scale-factor ()
112   (if golden-ratio-auto-scale
113       (- 1.0 (* (/ (- (frame-width) 100.0) 1000.0) 1.8))
114     golden-ratio-adjust-factor))
115
116 (defun golden-ratio--dimensions ()
117   (list (floor (/ (frame-height) golden-ratio--value))
118         (floor  (* (/ (frame-width)  golden-ratio--value)
119                    (golden-ratio--scale-factor)))))
120
121 (defun golden-ratio--resize-window (dimensions &optional window)
122   (with-selected-window (or window (selected-window))
123     (let ((nrow  (floor (- (first  dimensions) (window-height))))
124           (ncol  (floor (- (second dimensions) (window-width)))))
125       (when (window-resizable-p (selected-window) nrow)
126         (enlarge-window nrow))
127       (when (window-resizable-p (selected-window) ncol t)
128         (enlarge-window ncol t)))))
129
130 (defun golden-ratio-exclude-major-mode-p ()
131   "Returns non-nil if `major-mode' should not use golden-ratio."
132   (or (memq major-mode golden-ratio-exclude-modes)
133       (member (symbol-name major-mode)
134               golden-ratio-exclude-modes)))
135
136 ;;;###autoload
137 (defun golden-ratio (&optional arg)
138   "Resizes current window to the golden-ratio's size specs."
139   (interactive "p")
140   (unless (or (and (not golden-ratio-mode) (null arg))
141               (window-minibuffer-p)
142               (one-window-p)
143               (golden-ratio-exclude-major-mode-p)
144               (member (buffer-name)
145                       golden-ratio-exclude-buffer-names)
146               (and golden-ratio-exclude-buffer-regexp
147                 (loop for r in golden-ratio-exclude-buffer-regexp
148                          thereis (string-match r (buffer-name))))
149               (and golden-ratio-inhibit-functions
150                    (loop for fun in golden-ratio-inhibit-functions
151                          thereis (funcall fun))))
152     (let ((dims (golden-ratio--dimensions))
153           (golden-ratio-mode nil))
154       ;; Always disable `golden-ratio-mode' to avoid
155       ;; infinite loop in `balance-windows'.
156       (balance-windows)
157       (golden-ratio--resize-window dims)
158       (when golden-ratio-recenter
159         (scroll-right) (recenter)))))
160
161 ;; Should return nil
162 (defadvice other-window
163     (after golden-ratio-resize-window)
164   (golden-ratio) nil)
165
166 ;; Should return the buffer
167 (defadvice pop-to-buffer
168     (around golden-ratio-resize-window)
169   (prog1 ad-do-it (golden-ratio)))
170
171 (defun golden-ratio--post-command-hook ()
172   (when (or (memq this-command golden-ratio-extra-commands)
173             (and (consp this-command) ; A lambda form.
174                  (loop for com in golden-ratio-extra-commands
175                        thereis (or (memq com this-command)
176                                    (memq (car-safe com) this-command)))))
177     ;; This is needed in emacs-25 to avoid this error from `recenter':
178     ;; `recenter'ing a window that does not display current-buffer.
179     ;; This doesn't happen in emacs-24.4 and previous versions.
180     (run-with-idle-timer 0.01 nil (lambda () (golden-ratio)))))
181
182 (defun golden-ratio--mouse-leave-buffer-hook ()
183   (run-at-time 0.1 nil (lambda ()
184              (golden-ratio))))
185
186 ;;;###autoload
187 (define-minor-mode golden-ratio-mode
188     "Enable automatic window resizing with golden ratio."
189   :lighter " Golden"
190   :global t
191   (if golden-ratio-mode
192       (progn
193         (add-hook 'window-configuration-change-hook 'golden-ratio)
194         (add-hook 'post-command-hook 'golden-ratio--post-command-hook)
195         (add-hook 'mouse-leave-buffer-hook 'golden-ratio--mouse-leave-buffer-hook)
196         (ad-activate 'other-window)
197         (ad-activate 'pop-to-buffer))
198       (remove-hook 'window-configuration-change-hook 'golden-ratio)
199       (remove-hook 'post-command-hook 'golden-ratio--post-command-hook)
200       (remove-hook 'mouse-leave-buffer-hook 'golden-ratio--mouse-leave-buffer-hook)
201       (ad-deactivate 'other-window)
202       (ad-deactivate 'pop-to-buffer)))
203
204
205 (provide 'golden-ratio)
206
207 ;;; golden-ratio.el ends here